UNPKG

labo-components

Version:
201 lines (177 loc) 6.41 kB
import React from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import Project from '../../model/Project'; import Query from '../../model/Query'; import UserQuery from '../../model/UserQuery'; import ProjectAPI from '../../api/ProjectAPI'; import QueryAPI from '../../api/QueryAPI'; import IDUtil from '../../util/IDUtil'; import LocalStorageHandler from '../../util/LocalStorageHandler'; import MessageHelper from "../helpers/MessageHelper"; import FlexBox from '../FlexBox'; import ProjectQueriesTable from '../workspace/projects/query/ProjectQueriesTable'; import ProjectList from "../workspace/projects/ProjectList"; class QueryEditor extends React.PureComponent { constructor(props) { super(props); this.state = { errorMessage: false, selectedProject: this.props.project }; this.queryNameRef = React.createRef(); this.CLASS_PREFIX = 'qed'; } //communicate the result back to the owning component onOutput(data) { if(data) { this.setState({ project: data.project }) } if(this.props.onOutput) { this.props.onOutput(this.constructor.name, data); } } save = e => { e.preventDefault(); // require query name value if(!this.queryNameRef.current.value){ this.setState({ errorMessage: true }); return; } if(this.props.query) { const project = this.state.selectedProject; const userQuery = UserQuery.constructFromQuery( this.props.query, this.props.user.id, this.props.project.id, this.queryNameRef.current.value ); QueryAPI.save(this.props.user.id, this.props.project.id, userQuery, savedQuery => { if(savedQuery){ this.props.project.queries.push({ name : savedQuery.name, id: savedQuery.id, query : savedQuery.query }); this.onOutput({project : this.props.project, queryName: savedQuery.name}); //update in local storage too LocalStorageHandler.storeJSONInLocalStorage( 'stored-active-project', this.props.project.toLocalStorageObject() ); } else { alert('An error occurred while saving this query'); this.onOutput(null); } }); } else { //this should never happen though alert('An error occurred while saving this query'); this.onOutput(null); } }; onSelectProject = project => { if(project && project.name) { this.setState({ selectedProject: project }) } }; //----------------------------- RENDER FUNCTIONS ------------------------------- renderValidationFailed = () => { return ( <div className={IDUtil.cssClassName('validation-error', this.CLASS_PREFIX)}> Please name the query before saving it. </div> ); }; renderProjectList = (activeProject, userProjects, user, onSelectProject) => ( <ProjectList buttonText="Set active project" activeProject={activeProject} onSelect={onSelectProject} projects={userProjects} user={user} projectIcon={true} /> ); renderQueryForm = errorMessage => { return ( <form onSubmit={this.save}> <input type="text" ref={this.queryNameRef} placeholder="Name your query"/> <button type="submit" className="btn btn-light">Save</button> {errorMessage ? this.renderValidationFailed() : null} </form> ); }; renderQueryDetails = (query, collectionConfig) => ( <div className={IDUtil.cssClassName('query-params', this.CLASS_PREFIX)}> {MessageHelper.renderQuery(query, collectionConfig)} </div> ); renderQueryTable = (project, user) => { if(project === null || project.queries.length === 0) { return null; } return ( <FlexBox isVisible={false} title={'Other queries saved in: ' + project.name}> <div className={[ IDUtil.cssClassName('no-bootstrap-custom-styling'), IDUtil.cssClassName('table', this.CLASS_PREFIX)].join(' ') }> <ProjectQueriesTable project={project} user={user}/> </div> </FlexBox> ); }; render() { const projectList = this.renderProjectList( this.state.selectedProject, this.props.userProjects, this.props.user, this.onSelectProject ); const queryForm = this.state.selectedProject ? this.renderQueryForm(this.state.errorMessage): null; const queryDetails = this.state.selectedProject ? this.renderQueryDetails( this.props.query, this.props.collectionConfig ) : null; const queryTable = this.state.selectedProject ? this.renderQueryTable(this.state.selectedProject, this.props.user) : null ; return ( <div className={IDUtil.cssClassName('query-editor')}> <div title={this.state.selectedProject ? "Current user project. Click to change." : ""} style={{float: this.state.selectedProject ? 'right' : 'none'}} > {projectList} </div> {queryForm} {queryDetails} {queryTable} </div> ) } } QueryEditor.propTypes = { // current user object used for defining access roles per project user: PropTypes.shape({ id: PropTypes.string.isRequired, name: PropTypes.string, attributes: PropTypes.shape({ allowPersonalCollections: PropTypes.bool }) }), userProjects : PropTypes.array, project: Project.getPropTypes(false), collectionConfig : PropTypes.object.isRequired, query: PropTypes.object.isRequired, onOutput: PropTypes.func.isRequired }; export default QueryEditor;