UNPKG

labo-components

Version:
211 lines (194 loc) 6.94 kB
import React from 'react'; import PropTypes from 'prop-types'; import Project from '../../../model/Project'; import ComponentUtil from '../../../util/ComponentUtil'; import IDUtil from '../../../util/IDUtil'; import ProjectForm from './crud/ProjectForm'; import ProjectAPI from '../../../api/ProjectAPI'; /** * Returns the project list and send it to the output callback. * * FIXME this component does not handle new properties yet! (e.g. if you pass a new this.props.projects, the project list is NOT updated at all) */ export default class ProjectList extends React.Component { constructor(props) { super(props); this.state = { allProjects: this.props.projects || [], visibleProjects: this.props.projects || [], showNewProjectForm: false }; this.filterField = React.createRef(); this.CLASS_PREFIX = 'prl'; } onProjectSaved = project => { if (project) { const projects = [...this.state.allProjects, project]; this.setState( { showNewProjectForm: false, allProjects: projects, visibleProjects: projects }, () => this.selectProject(project.id) ); } }; handleProjectClicked = e => { this.selectProject(e.target.id); }; selectProject = projectId => { const selectedProject = this.state.allProjects.filter( item => item.id === projectId ); this.props.onSelect(selectedProject[0]); if (this.filterField.current) { this.filterField.current.value = ''; this.filterProjects(); } }; filterProjects = () => { const filteredProjects = this.state.allProjects.filter(item => item.name .toLowerCase() .includes(this.filterField.current.value.toLowerCase()) ); this.setState({ visibleProjects: filteredProjects }); }; newProject = () => { this.setState({ showNewProjectForm: true }); }; renderProjectForm = () => ( <ProjectForm id="bg__project-selector" submitButton="save" onCancel={() => { ComponentUtil.hideModal( this, 'showNewProjectForm', 'project__modal', true ); }} project={{ name: '', description: '', user: this.props.user.id }} projectDidSave={projectId => { ProjectAPI.get( this.props.user.id, projectId, project => { if (project && project.id) { this.onProjectSaved(project); } } ); ComponentUtil.hideModal( this, 'showNewProjectForm', 'project__modal', true ); }} user={this.props.user} api={ProjectAPI} /> ); renderProjectsList = modalOpened => { // remove active project from list of available options const listItems = this.props.activeProject ? this.state.visibleProjects.filter( item => item.name !== this.props.activeProject.name ) : this.state.visibleProjects; const menuClasses = [IDUtil.cssClassName('menu', this.CLASS_PREFIX)] if(modalOpened) { menuClasses.push('hidden'); } // only show filter if there are more than N items (or something is typed in the filter) const showFilter = (this.filterField.current && this.filterField.current.value.length > 0) || listItems.length > 8; return ( <ul className={menuClasses.join(' ')}> {showFilter && ( <input ref={this.filterField} type="text" onChange={this.filterProjects} placeholder="Filter projects" className={IDUtil.cssClassName( 'filter-list', this.CLASS_PREFIX )} /> )} {listItems.map(item => ( <li id={item.id} key={item.id} onClick={this.handleProjectClicked} > {item.name} </li> ))} <button onClick={this.newProject} className={IDUtil.cssClassName('new', this.CLASS_PREFIX)} > {' '} + New Project </button> </ul> ); }; render() { const projectList = this.renderProjectsList(this.state.showNewProjectForm); const newProjectForm = this.state.showNewProjectForm ? this.renderProjectForm(this.props.newProjectInModal) : null; return ( <label className={IDUtil.cssClassName('project-list')}> {this.props.activeProject && (this.props.activeProject.name !== null) ? ( <div className="active-project"> <div className={this.props.projectIcon ? 'title with-icon' : 'title'}> {this.props.activeProject.name} </div> <a href={ '/workspace/projects/' + this.props.activeProject.id } /> </div> ) : ( <div className="select">{this.props.buttonText}</div> )} <input type="checkbox" className={IDUtil.cssClassName( 'checkbox', this.CLASS_PREFIX )} /> {projectList} {newProjectForm} </label> ); } } ProjectList.propTypes = { onSelect: PropTypes.func.isRequired, buttonText: PropTypes.string.isRequired, projects: PropTypes.array, activeProject: Project.getPropTypes(false), user: PropTypes.shape({ id: PropTypes.string.isRequired, name: PropTypes.string, attributes: PropTypes.shape({ allowPersonalCollections: PropTypes.bool }) }).isRequired, projectIcon: PropTypes.bool //whether or not to show the project icon };