labo-components
Version:
201 lines (177 loc) • 6.41 kB
JSX
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;