From 9bee093eee7e1736c47844d7e19d754b27e3ab8d Mon Sep 17 00:00:00 2001 From: jagerts <94642410+jagerts@users.noreply.github.com> Date: Wed, 1 Jun 2022 14:20:52 +0300 Subject: [PATCH] validate url of Add data modal (#1837) * fix modal styles Signed-off-by: Evgeny Zhgulev * validate url input Signed-off-by: Evgeny Zhgulev * add http to url regexp Signed-off-by: Evgeny Zhgulev * fix linter error Signed-off-by: Evgeny Zhgulev --- .../load-data-modal/load-remote-map.js | 22 +++++++++++++------ examples/demo-app/src/utils/url.js | 8 +++++++ src/components/modal-container.tsx | 3 +++ src/components/side-panel/common/types.ts | 2 +- 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/examples/demo-app/src/components/load-data-modal/load-remote-map.js b/examples/demo-app/src/components/load-data-modal/load-remote-map.js index 80a3b57038..27ec95c773 100644 --- a/examples/demo-app/src/components/load-data-modal/load-remote-map.js +++ b/examples/demo-app/src/components/load-data-modal/load-remote-map.js @@ -25,6 +25,7 @@ import styled from 'styled-components'; import {CORS_LINK} from '../../constants/default-settings'; import {FormattedHTMLMessage, FormattedMessage} from 'react-intl'; import {Button} from 'kepler.gl/components'; +import {validateUrl} from '../../utils/url'; const propTypes = { onLoadRemoteMap: PropTypes.func.isRequired @@ -92,19 +93,24 @@ const Error = ({error, url}) => ( class LoadRemoteMap extends Component { state = { - dataUrl: '' + dataUrl: '', + error: null, + submitted: false }; onMapUrlChange = e => { - // TODO: validate url this.setState({ - dataUrl: e.target.value + dataUrl: e.target.value, + error: !validateUrl(e.target.value) ? {message: 'Incorrect URL'} : null }); }; onLoadRemoteMap = () => { - const {dataUrl} = this.state; - if (!dataUrl) { + const {dataUrl, error} = this.state; + + this.setState({submitted: true}); + + if (!dataUrl || error) { return; } @@ -112,6 +118,8 @@ class LoadRemoteMap extends Component { }; render() { + const displayedError = this.props.error || this.state.submitted ? this.state.error : null; + return (
@@ -138,13 +146,13 @@ class LoadRemoteMap extends Component { type="text" placeholder="Url" value={this.state.dataUrl} - error={this.props.error} + error={displayedError} /> - {this.props.error && } + {displayedError && }
); diff --git a/examples/demo-app/src/utils/url.js b/examples/demo-app/src/utils/url.js index 4cbecddf5f..78a6a62fcf 100644 --- a/examples/demo-app/src/utils/url.js +++ b/examples/demo-app/src/utils/url.js @@ -66,3 +66,11 @@ parseUri.options = { loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ } }; + +/** + * Validates an url + * @param str + */ +export function validateUrl(str) { + return str?.match(/^(ftp|http|https?):\/\/+(www\.)?[a-z0-9\-\.]{3,}\.[a-z]{3}$/); +} diff --git a/src/components/modal-container.tsx b/src/components/modal-container.tsx index 901ca18281..ef490b84ea 100644 --- a/src/components/modal-container.tsx +++ b/src/components/modal-container.tsx @@ -20,6 +20,7 @@ import React, {Component} from 'react'; import {css} from 'styled-components'; +import {findDOMNode} from 'react-dom'; import {createSelector} from 'reselect'; import get from 'lodash.get'; import document from 'global/document'; @@ -274,6 +275,7 @@ export default function ModalContainerFactory( mapState, uiState, visState, + rootNode, visStateActions, uiStateActions, providerState @@ -545,6 +547,7 @@ export default function ModalContainerFactory( return this.props.rootNode ? ( findDOMNode(rootNode)} isOpen={Boolean(currentModal)} onCancel={this._closeModal} {...modalProps} diff --git a/src/components/side-panel/common/types.ts b/src/components/side-panel/common/types.ts index abf5e4f331..1235031036 100644 --- a/src/components/side-panel/common/types.ts +++ b/src/components/side-panel/common/types.ts @@ -59,7 +59,7 @@ export type DatasetItemProps = { }; export type SourceDataSelectorProps = { - dataId: string | string[]; + dataId: string | string[] | null; datasets: Datasets; disabled: boolean; defaultValue?: string;