mirror of
https://github.com/maputnik/editor.git
synced 2026-08-24 14:07:33 +00:00
Merge pull request #330 from orangemug/feature/loading-modal
Loading dialog
This commit is contained in:
@@ -0,0 +1,49 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
|
import Button from '../Button'
|
||||||
|
import Modal from './Modal'
|
||||||
|
|
||||||
|
|
||||||
|
class LoadingModal extends React.Component {
|
||||||
|
static propTypes = {
|
||||||
|
isOpen: PropTypes.bool.isRequired,
|
||||||
|
onCancel: PropTypes.func.isRequired,
|
||||||
|
title: PropTypes.string.isRequired,
|
||||||
|
message: PropTypes.node.isRequired,
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
underlayOnClick(e) {
|
||||||
|
// This stops click events falling through to underlying modals.
|
||||||
|
e.stopPropagation();
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return <Modal
|
||||||
|
data-wd-key="loading-modal"
|
||||||
|
isOpen={this.props.isOpen}
|
||||||
|
underlayClickExits={false}
|
||||||
|
underlayProps={{
|
||||||
|
onClick: (e) => underlayProps(e)
|
||||||
|
}}
|
||||||
|
closeable={false}
|
||||||
|
title={this.props.title}
|
||||||
|
onOpenToggle={() => this.props.onCancel()}
|
||||||
|
>
|
||||||
|
<p>
|
||||||
|
{this.props.message}
|
||||||
|
</p>
|
||||||
|
<p className="maputnik-dialog__buttons">
|
||||||
|
<Button onClick={(e) => this.props.onCancel(e)}>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
</p>
|
||||||
|
</Modal>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default LoadingModal
|
||||||
@@ -11,6 +11,12 @@ class Modal extends React.Component {
|
|||||||
title: PropTypes.string.isRequired,
|
title: PropTypes.string.isRequired,
|
||||||
onOpenToggle: PropTypes.func.isRequired,
|
onOpenToggle: PropTypes.func.isRequired,
|
||||||
children: PropTypes.node,
|
children: PropTypes.node,
|
||||||
|
underlayClickExits: PropTypes.bool,
|
||||||
|
underlayProps: PropTypes.object,
|
||||||
|
}
|
||||||
|
|
||||||
|
static defaultProps = {
|
||||||
|
underlayClickExits: true
|
||||||
}
|
}
|
||||||
|
|
||||||
getApplicationNode() {
|
getApplicationNode() {
|
||||||
@@ -21,6 +27,8 @@ class Modal extends React.Component {
|
|||||||
if(this.props.isOpen) {
|
if(this.props.isOpen) {
|
||||||
return <AriaModal
|
return <AriaModal
|
||||||
titleText={this.props.title}
|
titleText={this.props.title}
|
||||||
|
underlayClickExits={this.props.underlayClickExits}
|
||||||
|
underlayProps={this.props.underlayProps}
|
||||||
getApplicationNode={this.getApplicationNode}
|
getApplicationNode={this.getApplicationNode}
|
||||||
data-wd-key={this.props["data-wd-key"]}
|
data-wd-key={this.props["data-wd-key"]}
|
||||||
verticallyCenter={true}
|
verticallyCenter={true}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
import LoadingModal from './LoadingModal'
|
||||||
import Modal from './Modal'
|
import Modal from './Modal'
|
||||||
import Button from '../Button'
|
import Button from '../Button'
|
||||||
import FileReaderInput from 'react-file-reader-input'
|
import FileReaderInput from 'react-file-reader-input'
|
||||||
@@ -60,13 +61,33 @@ class OpenModal extends React.Component {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onCancelActiveRequest(e) {
|
||||||
|
// Else the click propagates to the underlying modal
|
||||||
|
if(e) e.stopPropagation();
|
||||||
|
|
||||||
|
if(this.state.activeRequest) {
|
||||||
|
this.state.activeRequest.abort();
|
||||||
|
this.setState({
|
||||||
|
activeRequest: null,
|
||||||
|
activeRequestUrl: null
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onStyleSelect(styleUrl) {
|
onStyleSelect(styleUrl) {
|
||||||
this.clearError();
|
this.clearError();
|
||||||
|
|
||||||
request({
|
const reqOpts = {
|
||||||
url: styleUrl,
|
url: styleUrl,
|
||||||
withCredentials: false,
|
withCredentials: false,
|
||||||
}, (error, response, body) => {
|
}
|
||||||
|
|
||||||
|
const activeRequest = request(reqOpts, (error, response, body) => {
|
||||||
|
this.setState({
|
||||||
|
activeRequest: null,
|
||||||
|
activeRequestUrl: null
|
||||||
|
});
|
||||||
|
|
||||||
if (!error && response.statusCode == 200) {
|
if (!error && response.statusCode == 200) {
|
||||||
const mapStyle = style.ensureStyleValidity(JSON.parse(body))
|
const mapStyle = style.ensureStyleValidity(JSON.parse(body))
|
||||||
console.log('Loaded style ', mapStyle.id)
|
console.log('Loaded style ', mapStyle.id)
|
||||||
@@ -76,6 +97,11 @@ class OpenModal extends React.Component {
|
|||||||
console.warn('Could not open the style URL', styleUrl)
|
console.warn('Could not open the style URL', styleUrl)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
activeRequest: activeRequest,
|
||||||
|
activeRequestUrl: reqOpts.url
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
onOpenUrl() {
|
onOpenUrl() {
|
||||||
@@ -169,6 +195,13 @@ class OpenModal extends React.Component {
|
|||||||
{styleOptions}
|
{styleOptions}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<LoadingModal
|
||||||
|
isOpen={!!this.state.activeRequest}
|
||||||
|
title={'Loading style'}
|
||||||
|
onCancel={(e) => this.onCancelActiveRequest(e)}
|
||||||
|
message={"Loading: "+this.state.activeRequestUrl}
|
||||||
|
/>
|
||||||
</Modal>
|
</Modal>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -135,3 +135,9 @@
|
|||||||
color: $color-red;
|
color: $color-red;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.maputnik-dialog {
|
||||||
|
&__buttons {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user