Skip to content

Commit

Permalink
Add editor tutorials (#325)
Browse files Browse the repository at this point in the history
* Playing with joyride tutorial functionality for caclulator modal.

* Updated calculator tutorial and started colormap tutorial backend.

* Completed first draft for the Colormap joyride tutorial.

* Set-up joyride constants for use in tutorials. Perpared functionality fo template editor tutorials

* Minor changes to intro tutorial text

* Adding Templates joyride tutorial elemets

* Added functionality for a tutorial on loading variables.

* Finished up first draft for variable loading tutorial

* Updated .yaml files to have correct github link.

* Created an error boundary for the CachedFiles modal, to prevent stop application crash if file variables fail to load.

* Fixes to merged files.

* removed .yaml file because it gets generated anyway.

* Update meta.yaml and removed tabs from load variable modal.

* Created Proptype declarations for recently added props
  • Loading branch information
downiec committed Oct 22, 2018
1 parent 2bb6930 commit 5553af6
Show file tree
Hide file tree
Showing 11 changed files with 282 additions and 49 deletions.
4 changes: 2 additions & 2 deletions conda/meta.yaml.in
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ requirements:
- setuptools
- nodejs
run:
- python
- python =2
- flask
- vcs
- cdms2
Expand All @@ -24,4 +24,4 @@ build:
noarch_python: true

about:
home: http://gitub.com/UV-CDAT/vcdat
home: http://github.com/UV-CDAT/vcdat
2 changes: 1 addition & 1 deletion conda/meta.yaml.official
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
about:
home: http://gitub.com/UV-CDAT/vcdat
home: http://github.com/UV-CDAT/vcdat
package:
name: vcdat
version: "0.7.0"
Expand Down
6 changes: 5 additions & 1 deletion frontend/src/js/components/PlotInspector/PlotInspector.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,11 @@ class PlotInspector extends React.PureComponent {
</table>
</div>
{this.props.show_colormap_editor && (
<ColormapEditor startTour={this.props.startTour} show={this.props.show_colormap_editor} close={this.props.handleCloseColormapEditor} />
<ColormapEditor
startTour={this.props.startTour}
show={this.props.show_colormap_editor}
close={this.props.handleCloseColormapEditor}
/>
)}
</div>
);
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/js/components/TemplateList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ class TemplateList extends Component {
</ul>
</div>
<TemplateEditor
startTour={this.props.startTour}
show={this.state.showTemplateEditor}
close={/* istanbul ignore next */ () => this.setState({showTemplateEditor: false})}
template={this.state.template_data}
Expand All @@ -183,6 +184,7 @@ TemplateList.propTypes = {
selectTemplate: PropTypes.func,
updateTemplate: PropTypes.func,
removeTemplate: PropTypes.func,
startTour: PropTypes.func,
}

export default TemplateList;
2 changes: 2 additions & 0 deletions frontend/src/js/components/VarList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ class VarList extends Component {
</div>
<CachedFiles
show={this.state.showFile}
startTour={this.props.startTour}
onTryClose={()=>this.setState({ showFile: false })}
curVariables={this.props.variables}
loadVariables={this.props.loadVariables}
Expand All @@ -111,6 +112,7 @@ class VarList extends Component {
}

VarList.propTypes = {
startTour: PropTypes.func,
cachedFiles: PropTypes.object,
loadVariables: PropTypes.func,
variables: PropTypes.oneOfType([
Expand Down
55 changes: 39 additions & 16 deletions frontend/src/js/components/modals/CachedFiles/CachedFiles.jsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { Modal } from 'react-bootstrap'
import { Modal, Button } from 'react-bootstrap'
import './CachedFiles.scss'
import FileTab from './Tabs/FileTab.jsx'
// import Esgf from './Tabs/EsgfTab.jsx'
// import OpendapTab from './Tabs/OpendapTab.jsx'
import TabBar from '../../TabBar/TabBar.jsx'
// import TabBar from '../../TabBar/TabBar.jsx'

class CachedFiles extends Component {

constructor(props) {
super(props);
this.state = {
selected_tab: 0,
hasError: false,
/*selected_tab: 0,
tabs: [
{
id: "file",
Expand All @@ -27,35 +29,56 @@ class CachedFiles extends Component {
display_name: "OpenDAP",
disabled: true,
},
]
]*/
}
this.switchTab = this.switchTab.bind(this)
//this.switchTab = this.switchTab.bind(this)
}

switchTab(index){
this.setState({ selected_tab: index})
//Added this function to cause this component to become an error boundary and catch issues with loading files/variables.
componentDidCatch(error, info) {
this.setState({hasError: true});
console.log(error);
}
/*
switchTab(index){
this.setState({selected_tab: index});
}*/

render() {
return (
<Modal className='cached-files' bsSize="large" show={this.props.show} onHide={this.props.onTryClose}>
<Modal.Header closeButton>
<Modal.Title>{this.state.selected_tab === 3 ? "Variable Info" : "Load Variable"}</Modal.Title>
</Modal.Header>
<TabBar tabs={this.state.tabs} selected_tab={this.state.selected_tab} switchTab={this.switchTab} />
{
this.state.selected_tab == 1 ? <div className="Dummy-esgf-component">ESGF</div> :
this.state.selected_tab == 2 ? <div className="Dummy-opendap-component">OpenDAP</div> :
<FileTab {...this.props} />
}
<div id='load-variable-form'>
<Modal.Header closeButton>
{
/*this.state.selected_tab === 3 ? (
<Modal.Title>Variable Info</Modal.Title>
) : (*/
<Modal.Title>Load Variable &nbsp;
<Button onClick={() => this.props.startTour(3)} className='help-button main-help btn btn-xs btn-default'>
<i className='glyphicon glyphicon-question-sign' />Help
</Button>
</Modal.Title>
//)
}
</Modal.Header>
{/*<TabBar tabs={this.state.tabs} selected_tab={this.state.selected_tab} switchTab={this.switchTab} />*/}
{
//this.state.selected_tab == 1 ? <div className="Dummy-esgf-component">ESGF</div> :
//this.state.selected_tab == 2 ? <div className="Dummy-opendap-component">OpenDAP</div> :
<FileTab {...this.props} hasError={this.state.hasError} handleError={()=>{this.setState({hasError: false})}} />
}
</div>
</Modal>
)
}
}

CachedFiles.propTypes = {
show: PropTypes.bool.isRequired,
startTour: PropTypes.func,
onTryClose: PropTypes.func.isRequired,
hasError: PropTypes.bool.isRequired,
handleError: PropTypes.func.isRequired
}

export default CachedFiles
21 changes: 17 additions & 4 deletions frontend/src/js/components/modals/CachedFiles/Tabs/FileTab.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ class FileTab extends Component {
];
window.localStorage.setItem(HISTORY_KEY, JSON.stringify(historyFiles));
const selected_variable = getDefaultVariable(Object.keys(variablesAxes[0]));

self.setState({
variablesAxes,
selectedFile: file,
Expand Down Expand Up @@ -336,6 +337,11 @@ class FileTab extends Component {
if (this.state.selectedFile) {
selected_file_path = cleanPath(this.state.selectedFile.path) + "/" + this.state.selectedFile.name;
}
if(this.props.hasError){
this.props.handleError();
console.log("File info modal restarted due to error.");
toast.error("Error occurred loading file.", { position: toast.POSITION.BOTTOM_CENTER });
}
return (
<div>
<Modal.Body>
Expand All @@ -350,10 +356,10 @@ class FileTab extends Component {
File
</Col>
<Col sm={9}>
<InputGroup bsSize="small">
<InputGroup id='file-selection-field' bsSize="small">
<FormControl className="full-width file-path" type="text" value={this.selectedFilePath} />
<InputGroup.Button>
<Button bsStyle="primary" onClick={() => this.setState({ showFileExplorer: true })}>
<Button id='btn-open-file' bsStyle="primary" onClick={() => this.setState({ showFileExplorer: true })}>
<Glyphicon glyph="file" />
</Button>
<Button
Expand All @@ -372,7 +378,7 @@ class FileTab extends Component {
Variable(s)
</Col>
<Col sm={9}>
<FormControl
<FormControl id='select-variable'
className="input-sm full-width"
componentClass="select"
onChange={e => this.setState({ selectedVariableName: e.target.value })}
Expand All @@ -387,7 +393,10 @@ class FileTab extends Component {
History:
</Col>
<Col sm={9}>
<FormControl className="history" componentClass="div">
<FormControl
id='file-history-list'
className="history"
componentClass="div">
{this.state.historyFiles.map((file, i) => {
return (
<div
Expand Down Expand Up @@ -415,6 +424,7 @@ class FileTab extends Component {
</Col>
<Col sm={9}>
<FormControl
id='bookmark-list'
className="bookmarks"
componentClass="div"
style={{ backgroundColor: this.state.showBookmarkZone ? "#d1ecf1" : "#fff" }}
Expand Down Expand Up @@ -503,6 +513,7 @@ class FileTab extends Component {
</Modal.Body>
<Modal.Footer>
<Button
id='btn-load-variable'
bsStyle="primary"
onClick={e => {
this.load();
Expand All @@ -511,6 +522,7 @@ class FileTab extends Component {
Load
</Button>
<Button
id='btn-load-variable-close'
bsStyle="primary"
onClick={e => {
this.loadAndClose();
Expand All @@ -519,6 +531,7 @@ class FileTab extends Component {
Load and Close
</Button>
<Button
id='btn-load-variable-as'
bsStyle="primary"
onClick={e => {
this.loadAs();
Expand Down
49 changes: 31 additions & 18 deletions frontend/src/js/components/modals/TemplateEditor.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,26 +54,38 @@ class TemplateEditor extends Component {

render() {
const template_name = this.props.template && typeof this.props.template === "object" ? this.props.template.name : "";

return (
<Modal show={this.props.show} onHide={this.props.close}>
<Modal.Header closeButton>
<Modal.Title>Edit {template_name}</Modal.Title>
</Modal.Header>
<Modal.Body>
{
this.props.template === "loading" ? <div style={{display: "flex", justifyContent: "center"}}><span className="loading-spinner"></span></div>
: this.props.template === "error" ? <div id="template-load-error">Error retrieving template data. Try another template, or restart vCDAT. If the problem persists, please send an email to cdat-support@llnl.gov detailing the issue.</div>
: <TemplateEdit
templatePreview={"/plotTemplate?tmpl=" + JSON.stringify(this.state.workingTemplate)}
template={this.state.workingTemplate}
updateTemplate={this.onUpdate}
/>
}
</Modal.Body>
<Modal.Footer>
<Button onClick={this.saveTemplate} bsStyle="primary" disabled={this.props.template === "error"}>Save</Button>
<Button onClick={this.props.close} bsStyle="default">Cancel</Button>
</Modal.Footer>
<div id='template-editor-main'>
<Modal.Header closeButton>
<Modal.Title>Edit {template_name} &nbsp;
<Button onClick={() => this.props.startTour(3)} className="help-button main-help btn btn-xs btn-default">
<i className="glyphicon glyphicon-question-sign" />Help
</Button>
</Modal.Title>
</Modal.Header>
<Modal.Body>
{
this.props.template === "loading" ? <div style={{display: "flex", justifyContent: "center"}}><span className="loading-spinner"></span></div>
: this.props.template === "error" ?
<div id="template-load-error">
Error retrieving template data. Try another template, or restart vCDAT.
If the problem persists, please send an email to cdat-support@llnl.gov detailing the issue.
</div>
: <TemplateEdit
id="joyride-template-edit"
templatePreview={"/plotTemplate?tmpl=" + JSON.stringify(this.state.workingTemplate)}
template={this.state.workingTemplate}
updateTemplate={this.onUpdate}
/>
}
</Modal.Body>
<Modal.Footer>
<Button onClick={this.saveTemplate} bsStyle="primary" disabled={this.props.template === "error"}>Save</Button>
<Button onClick={this.props.close} bsStyle="default">Cancel</Button>
</Modal.Footer>
</div>
</Modal>
);
}
Expand All @@ -82,6 +94,7 @@ class TemplateEditor extends Component {
TemplateEditor.propTypes = {
show: PropTypes.bool,
close: PropTypes.func,
startTour: PropTypes.func,
template: PropTypes.oneOfType([
PropTypes.string, // valid states: "loading" or "error"
PropTypes.object, // template is an object if loading was successfull
Expand Down

0 comments on commit 5553af6

Please sign in to comment.