mirror of
https://github.com/muerwre/orchidmap-front.git
synced 2025-04-25 11:06:40 +07:00
nominatim search (without working dialog)
This commit is contained in:
parent
c3e136cebb
commit
b20a3445d1
27 changed files with 450 additions and 61 deletions
16
src/components/dialogs/DialogLoader.tsx
Normal file
16
src/components/dialogs/DialogLoader.tsx
Normal file
|
@ -0,0 +1,16 @@
|
|||
import React, { FC } from 'react';
|
||||
import { Icon } from '~/components/panels/Icon';
|
||||
|
||||
interface IProps {}
|
||||
|
||||
const DialogLoader: FC<IProps> = ({}) => {
|
||||
return (
|
||||
<div className="dialog-maplist-loader">
|
||||
<div className="dialog-maplist-icon spin">
|
||||
<Icon icon="icon-sync-1" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export { DialogLoader };
|
|
@ -24,6 +24,7 @@ import { IRouteListItem } from '~/redux/user';
|
|||
import { ROLES } from '~/constants/auth';
|
||||
import { IState } from '~/redux/store';
|
||||
import { MapListDialogHead } from '~/components/search/MapListDialogHead';
|
||||
import { DialogLoader } from '~/components/dialogs/DialogLoader';
|
||||
|
||||
const mapStateToProps = ({
|
||||
editor: { editing },
|
||||
|
@ -165,11 +166,7 @@ class MapListDialogUnconnected extends PureComponent<Props, State> {
|
|||
return (
|
||||
<div className="dialog-content full">
|
||||
{list.length === 0 && loading && (
|
||||
<div className="dialog-maplist-loader">
|
||||
<div className="dialog-maplist-icon spin">
|
||||
<Icon icon="icon-sync-1" />
|
||||
</div>
|
||||
</div>
|
||||
<DialogLoader />
|
||||
)}
|
||||
|
||||
{ready && !loading && list.length === 0 && (
|
||||
|
|
46
src/components/dialogs/NominatimDialog.tsx
Normal file
46
src/components/dialogs/NominatimDialog.tsx
Normal file
|
@ -0,0 +1,46 @@
|
|||
import React, { FC, Fragment, useCallback } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { IState } from '~/redux/store';
|
||||
import { selectEditorNominatim } from '~/redux/editor/selectors';
|
||||
import { DialogLoader } from './DialogLoader';
|
||||
import { NominatimListItem } from '~/components/nominatim/NominatimListItem';
|
||||
import { MainMap } from '~/constants/map';
|
||||
import { Scroll } from '../Scroll';
|
||||
|
||||
const mapStateToProps = (state: IState) => ({
|
||||
nominatim: selectEditorNominatim(state),
|
||||
});
|
||||
|
||||
type Props = ReturnType<typeof mapStateToProps> & {};
|
||||
|
||||
const NominatimDialogUnconnected: FC<Props> = ({ nominatim: { loading, list } }) => {
|
||||
const onItemClick = useCallback(
|
||||
(index: number) => {
|
||||
if (!list[index]) return;
|
||||
|
||||
MainMap.setView(list[index].latlng, 17);
|
||||
},
|
||||
[MainMap, list]
|
||||
);
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<div style={{ flex: 1 }} />
|
||||
|
||||
<div className="dialog-flex-scroll">
|
||||
<Scroll>
|
||||
<div className="dialog-content nominatim-dialog-content">
|
||||
{loading && <DialogLoader />}
|
||||
{list.map((item, i) => (
|
||||
<NominatimListItem item={item} key={item.id} />
|
||||
))}
|
||||
</div>
|
||||
</Scroll>
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
const NominatimDialog = connect(mapStateToProps)(NominatimDialogUnconnected);
|
||||
|
||||
export { NominatimDialog };
|
37
src/components/dialogs/NominatimSearchPanel.tsx
Normal file
37
src/components/dialogs/NominatimSearchPanel.tsx
Normal file
|
@ -0,0 +1,37 @@
|
|||
import React, { FC, useCallback, useState } from 'react';
|
||||
import { Icon } from '../panels/Icon';
|
||||
|
||||
interface IProps {
|
||||
active: boolean;
|
||||
onSearch: (search: string) => void;
|
||||
}
|
||||
|
||||
const NominatimSearchPanel: FC<IProps> = ({ active, onSearch }) => {
|
||||
const [search, setSearch] = useState('Колывань');
|
||||
|
||||
const setValue = useCallback(({ target: { value } }) => setSearch(value), [setSearch]);
|
||||
|
||||
const onSubmit = useCallback(event => {
|
||||
event.preventDefault();
|
||||
|
||||
if (search.length < 3) return;
|
||||
|
||||
onSearch(search);
|
||||
}, [search, onSearch]);
|
||||
|
||||
return (
|
||||
<form className="panel nominatim-panel active" onSubmit={onSubmit}>
|
||||
<div className="control-bar">
|
||||
<div className="nominatim-search-input">
|
||||
<input type="text" placeholder="Поиск на карте" value={search} onChange={setValue} />
|
||||
</div>
|
||||
|
||||
<button>
|
||||
<Icon icon="icon-search" />
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
||||
export { NominatimSearchPanel };
|
21
src/components/nominatim/NominatimListItem.tsx
Normal file
21
src/components/nominatim/NominatimListItem.tsx
Normal file
|
@ -0,0 +1,21 @@
|
|||
import React, { FC, useCallback } from 'react';
|
||||
import { INominatimResult } from '~/redux/types';
|
||||
import { MainMap } from '~/constants/map';
|
||||
|
||||
interface IProps {
|
||||
item: INominatimResult;
|
||||
}
|
||||
|
||||
const NominatimListItem: FC<IProps> = ({ item }) => {
|
||||
const onClick = useCallback(() => {
|
||||
MainMap.panTo(item.latlng);
|
||||
}, [MainMap]);
|
||||
|
||||
return (
|
||||
<div onClick={onClick} className="nominatim-list-item">
|
||||
<div className="title">{item.title}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export { NominatimListItem };
|
|
@ -32,7 +32,7 @@ type Props = ReturnType<typeof mapStateToProps> & typeof mapDispatchToProps & {}
|
|||
|
||||
class EditorPanelUnconnected extends PureComponent<Props, void> {
|
||||
componentDidMount() {
|
||||
window.addEventListener('keydown', this.props.editorKeyPressed as any);
|
||||
window.addEventListener('keydown', this.onKeyPress as any);
|
||||
|
||||
const obj = document.getElementById('control-dialog');
|
||||
const { width } = this.panel.getBoundingClientRect();
|
||||
|
@ -45,9 +45,15 @@ class EditorPanelUnconnected extends PureComponent<Props, void> {
|
|||
panel: HTMLElement = null;
|
||||
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener('keydown', this.props.editorKeyPressed as any);
|
||||
window.removeEventListener('keydown', this.onKeyPress as any);
|
||||
}
|
||||
|
||||
onKeyPress = event => {
|
||||
if (event.target.tagName === 'TEXTAREA' || event.target.tagName === 'INPUT') return;
|
||||
|
||||
this.props.editorKeyPressed(event);
|
||||
};
|
||||
|
||||
startPolyMode = () => this.props.editorSetMode(MODES.POLY);
|
||||
startStickerMode = () => this.props.editorSetMode(MODES.STICKERS_SELECT);
|
||||
startRouterMode = () => this.props.editorSetMode(MODES.ROUTER);
|
||||
|
|
|
@ -10,6 +10,7 @@ import {
|
|||
editorSetDialog,
|
||||
editorSetDialogActive,
|
||||
editorGetGPXTrack,
|
||||
editorSearchNominatim,
|
||||
} from '~/redux/editor/actions';
|
||||
import { connect } from 'react-redux';
|
||||
import { Icon } from '~/components/panels/Icon';
|
||||
|
@ -19,11 +20,12 @@ import { CLIENT } from '~/config/frontend';
|
|||
import { DIALOGS, TABS } from '~/constants/dialogs';
|
||||
import { Tooltip } from '~/components/panels/Tooltip';
|
||||
import { TitleDialog } from '~/components/dialogs/TitleDialog';
|
||||
import { NominatimSearchPanel } from '~/components/dialogs/NominatimSearchPanel';
|
||||
import { IState } from '~/redux/store';
|
||||
|
||||
const mapStateToProps = ({
|
||||
user: { user },
|
||||
editor: { dialog, dialog_active },
|
||||
editor: { dialog, dialog_active, features },
|
||||
map: { route, stickers },
|
||||
}: IState) => ({
|
||||
dialog,
|
||||
|
@ -31,6 +33,7 @@ const mapStateToProps = ({
|
|||
user,
|
||||
route,
|
||||
stickers,
|
||||
features,
|
||||
});
|
||||
|
||||
const mapDispatchToProps = {
|
||||
|
@ -42,6 +45,7 @@ const mapDispatchToProps = {
|
|||
editorSetDialogActive,
|
||||
openMapDialog,
|
||||
editorGetGPXTrack,
|
||||
editorSearchNominatim,
|
||||
};
|
||||
|
||||
type Props = ReturnType<typeof mapStateToProps> & typeof mapDispatchToProps & {};
|
||||
|
@ -90,6 +94,7 @@ export class UserPanelUnconnected extends PureComponent<Props, State> {
|
|||
}
|
||||
|
||||
setMenuOpened = () => this.setState({ menuOpened: !this.state.menuOpened });
|
||||
|
||||
openMapsDialog = () => {
|
||||
this.props.openMapDialog(TABS.MY);
|
||||
};
|
||||
|
@ -115,7 +120,7 @@ export class UserPanelUnconnected extends PureComponent<Props, State> {
|
|||
|
||||
render() {
|
||||
const {
|
||||
props: { user, dialog, dialog_active, route, stickers },
|
||||
props: { user, dialog, dialog_active, route, stickers, features },
|
||||
state: { menuOpened },
|
||||
} = this;
|
||||
|
||||
|
@ -124,6 +129,7 @@ export class UserPanelUnconnected extends PureComponent<Props, State> {
|
|||
return (
|
||||
<div>
|
||||
<TitleDialog />
|
||||
<NominatimSearchPanel active={features.nominatim} onSearch={this.props.editorSearchNominatim} />
|
||||
|
||||
<div className="panel active panel-user">
|
||||
<div className="user-panel">
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue