terriajs
Version:
Geospatial data visualization platform.
116 lines • 6.78 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { action, runInAction } from "mobx";
import { observer } from "mobx-react";
import PropTypes from "prop-types";
import { useEffect, useRef } from "react";
import { useTranslation } from "react-i18next";
import styled, { useTheme } from "styled-components";
import { addMarker, removeMarker } from "../../Models/LocationMarkerUtils";
import Box from "../../Styled/Box";
import { RawButton } from "../../Styled/Button";
import Icon, { StyledIcon } from "../../Styled/Icon";
import Spacing from "../../Styled/Spacing";
import Text from "../../Styled/Text";
import { useViewState } from "../Context";
import LocationSearchResults from "./LocationSearchResults";
import SearchBox from "./SearchBox";
export function SearchInDataCatalog({ handleClick }) {
const viewState = useViewState();
const locationSearchText = viewState.searchState.locationSearchText;
const { t } = useTranslation();
return (_jsx(RawButton, { fullWidth: true, onClick: () => {
const { searchState } = viewState;
// Set text here as a separate action so that it doesn't get batched up and the catalog
// search text has a chance to set isWaitingToStartCatalogSearch
searchState.setCatalogSearchText(searchState.locationSearchText);
viewState.searchInCatalog(searchState.locationSearchText);
if (handleClick) {
handleClick();
}
}, children: _jsxs(Box, { paddedRatio: 2, rounded: true, charcoalGreyBg: true, children: [_jsx(StyledIcon, { styledWidth: "14px", glyph: Icon.GLYPHS["dataCatalog"] }), _jsx(Spacing, { right: 2 }), _jsx(Text, { textAlignLeft: true, textLight: true, large: true, fullWidth: true, children: t("search.searchInDataCatalog", {
locationSearchText: locationSearchText
}) }), _jsx(StyledIcon, { glyph: Icon.GLYPHS.right2, styledWidth: "14px", light: true })] }) }));
}
SearchInDataCatalog.propTypes = {
handleClick: PropTypes.func.isRequired,
viewState: PropTypes.object.isRequired
};
const PresentationBox = styled(Box).attrs({
fullWidth: true
}) `
${(props) => props.highlightBottom &&
`
// styled-components doesn't seem to prefix linear-gradient.. soo
background-image: linear-gradient(bottom, ${props.theme.greyLightest} 50%, transparent 50%);
background-image: -o-linear-gradient(bottom, ${props.theme.greyLightest} 50%, transparent 50%);
background-image: -moz-linear-gradient(bottom, ${props.theme.greyLightest} 50%, transparent 50%);
background-image: -webkit-linear-gradient(bottom, ${props.theme.greyLightest} 50%, transparent 50%);
background-image: -ms-linear-gradient(bottom, ${props.theme.greyLightest} 50%, transparent 50%);
`}
`;
export const LOCATION_SEARCH_INPUT_NAME = "LocationSearchInput";
export const SearchBoxAndResults = observer(({ placeholder }) => {
const locationSearchRef = useRef(null);
const viewState = useViewState();
const theme = useTheme();
useEffect(() => {
viewState.updateAppRef(LOCATION_SEARCH_INPUT_NAME, locationSearchRef);
}, [viewState]);
const toggleShowLocationSearchResults = action((bool) => {
viewState.searchState.showLocationSearchResults = bool;
});
const changeSearchText = (newText) => {
runInAction(() => {
viewState.searchState.locationSearchText = newText;
});
if (newText.length === 0) {
removeMarker(viewState.terria);
runInAction(() => {
toggleShowLocationSearchResults(false);
});
}
if (newText.length > 0 &&
!viewState.searchState.showLocationSearchResults) {
runInAction(() => {
toggleShowLocationSearchResults(true);
});
}
};
const search = () => {
viewState.searchState.searchLocations();
};
const startLocationSearch = () => {
toggleShowLocationSearchResults(true);
};
const searchState = viewState.searchState;
const locationSearchText = searchState.locationSearchText;
const shouldShowResults = searchState.locationSearchText.length > 0 &&
searchState.showLocationSearchResults;
return (_jsx(Text, { textDarker: true, children: _jsxs(Box, { fullWidth: true, children: [_jsx(PresentationBox, { highlightBottom: shouldShowResults, children: _jsx(SearchBox, { ref: locationSearchRef, onSearchTextChanged: changeSearchText, onDoSearch: search, onFocus: startLocationSearch, searchText: searchState.locationSearchText, placeholder: placeholder, supportsAutocomplete: searchState.supportsAutocomplete }) }), shouldShowResults && (_jsxs(Box, { position: "absolute", fullWidth: true, column: true, css: `
top: 100%;
background-color: ${theme.greyLightest};
max-height: calc(100vh - 200px);
border-radius: 0 0 ${theme.radiusLarge} ${theme.radiusLarge};
overflow: hidden;
`, children: [viewState.terria.searchBarModel.showSearchInCatalog &&
searchState.catalogSearchProvider && (_jsx(Box, { column: true, paddedRatio: 2, children: _jsx(SearchInDataCatalog, { viewState: viewState, handleClick: () => {
toggleShowLocationSearchResults(false);
} }) })), _jsx(Box, { column: true, css: `
overflow-y: auto;
`, children: !searchState.isWaitingToStartLocationSearch &&
searchState.locationSearchResults.map((search) => (_jsx(LocationSearchResults, { terria: viewState.terria, viewState: viewState, search: search, locationSearchText: locationSearchText, onLocationClick: (result) => {
if (!result.location)
return;
addMarker(viewState.terria, {
name: result.name,
location: result.location
});
result.clickAction?.();
runInAction(() => {
searchState.showLocationSearchResults = false;
});
}, isWaitingForSearchToStart: searchState.isWaitingToStartLocationSearch }, search.searchProvider.uniqueId))) })] }))] }) }));
});
SearchBoxAndResults.displayName = "SearchBoxAndResults";
export default SearchBoxAndResults;
//# sourceMappingURL=SearchBoxAndResults.js.map