terriajs
Version:
Geospatial data visualization platform.
196 lines (173 loc) • 7.34 kB
JSX
import React from 'react';
import createReactClass from 'create-react-class';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import addUserCatalogMember from '../../../../Models/addUserCatalogMember';
import createCatalogItemFromFileOrUrl from '../../../../Models/createCatalogItemFromFileOrUrl';
import createCatalogMemberFromType from '../../../../Models/createCatalogMemberFromType';
import Dropdown from '../../../Generic/Dropdown';
import FileInput from './FileInput.jsx';
import getDataType from '../../../../Core/getDataType';
import ObserveModelMixin from '../../../ObserveModelMixin';
import TerriaError from '../../../../Core/TerriaError';
import addUserFiles from '../../../../Models/addUserFiles';
import Styles from './add-data.scss';
// Local and remote data have different dataType options
const remoteDataType = getDataType().remoteDataType;
const localDataType = getDataType().localDataType;
/**
* Add data panel in modal window -> My data tab
*/
const AddData = createReactClass({
displayName: 'AddData',
mixins: [ObserveModelMixin],
propTypes: {
terria: PropTypes.object,
viewState: PropTypes.object
},
getInitialState() {
return {
localDataType: localDataType[0], // By default select the first item (auto)
remoteDataType: remoteDataType[0],
activeTab: 'local', // By default local data tab is active
remoteUrl: '' // By default there's no remote url
};
},
selectLocalOption(option) {
this.setState({
localDataType: option
});
},
selectRemoteOption(option) {
this.setState({
remoteDataType: option
});
},
changeTab(active) {
this.setState({
activeTab: active
});
},
handleUploadFile(e) {
addUserFiles(e.target.files, this.props.terria, this.props.viewState, this.state.localDataType)
.then(addedCatalogItems => {
if (addedCatalogItems.length > 0) {
this.onFileAddFinished(addedCatalogItems[0]);
}
});
},
handleUrl(e) {
const url = this.state.remoteUrl;
e.preventDefault();
this.props.terria.analytics.logEvent('addDataUrl', url);
const that = this;
let promise;
if (that.state.remoteDataType.value === 'auto') {
promise = loadFile(that);
} else {
const newItem = createCatalogMemberFromType(that.state.remoteDataType.value, that.props.terria);
newItem.name = that.state.remoteUrl;
newItem.url = that.state.remoteUrl;
promise = newItem.load().then(function () {
return newItem;
});
}
addUserCatalogMember(this.props.terria, promise).then(addedItem => {
if (addedItem && !(addedItem instanceof TerriaError)) {
this.onFileAddFinished(addedItem);
}
});
},
onFileAddFinished(fileToSelect) {
this.props.viewState.myDataIsUploadView = false;
this.props.viewState.viewCatalogMember(fileToSelect);
},
onRemoteUrlChange(event) {
this.setState({
remoteUrl: event.target.value
});
},
renderTabs() {
const tabs = [{
id: 'local',
caption: 'Add Local Data'
}, {
id: 'web',
caption: 'Add Web Data'
}];
return (
<ul className={Styles.tabList}>
<For each="tab" of={tabs}>
<li className={Styles.tabListItem} key={tab.id}>
<button type='button' onClick={this.changeTab.bind(null, tab.id)}
className={classNames(Styles.tabListBtn, {[Styles.isActive]: this.state.activeTab === tab.id})}>
{tab.caption}
</button>
</li>
</For>
</ul>
);
},
renderPanels() {
const dropdownTheme = {
dropdown: Styles.dropdown,
list: Styles.dropdownList,
isOpen: Styles.dropdownListIsOpen
};
const dataTypes = localDataType.reduce(function(result, currentDataType) {
if (currentDataType.extensions) {
return result.concat(currentDataType.extensions.map(extension => '.' + extension));
} else {
return result;
}
}, []);
return (
<div className={Styles.tabPanels}>
<If condition={this.state.activeTab === 'local'}>
<section className={Styles.tabPanel}>
<label className={Styles.label}><strong>Step 1:</strong> Select type of file to add: </label>
<Dropdown options={localDataType} selected={this.state.localDataType}
selectOption={this.selectLocalOption} matchWidth={true} theme={dropdownTheme}/>
<label className={Styles.label}><strong>Step 2:</strong> Select a local data file to add:
</label>
<FileInput accept={dataTypes.join(',')} onChange={this.handleUploadFile}/>
</section>
</If>
<If condition={this.state.activeTab === 'web'}>
<section className={Styles.tabPanel}>
<label className={Styles.label}><strong>Step 1:</strong> Select type of file to add: </label>
<Dropdown options={remoteDataType} selected={this.state.remoteDataType}
selectOption={this.selectRemoteOption} matchWidth={true} theme={dropdownTheme}/>
<label className={Styles.label}><strong>Step 2:</strong> Enter the URL of the data file or web
service:
</label>
<form className={Styles.urlInput}>
<input value={this.state.remoteUrl} onChange={this.onRemoteUrlChange}
className={Styles.urlInputTextBox}
type='text'
placeholder='e.g. http://data.gov.au/geoserver/wms'/>
<button type='submit' onClick={this.handleUrl} className={Styles.urlInputBtn}>
Add
</button>
</form>
</section>
</If>
</div>
);
},
render() {
return (
<div className={Styles.inner}>
{this.renderTabs()}
{this.renderPanels()}
</div>
);
},
});
/**
* Loads a catalog item from a file.
*/
function loadFile(viewModel) {
return createCatalogItemFromFileOrUrl(viewModel.props.terria, viewModel.props.viewState, viewModel.state.remoteUrl, viewModel.state.remoteDataType.value, true);
}
module.exports = AddData;