p5.js-web-editor/client/modules/IDE/components/AddToCollectionList.jsx
2020-08-19 16:40:59 -04:00

167 lines
4.6 KiB
JavaScript

import PropTypes from 'prop-types';
import React from 'react';
import { Helmet } from 'react-helmet';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import * as ProjectActions from '../actions/project';
import * as ProjectsActions from '../actions/projects';
import * as CollectionsActions from '../actions/collections';
import * as ToastActions from '../actions/toast';
import * as SortingActions from '../actions/sorting';
import getSortedCollections from '../selectors/collections';
import Loader from '../../App/components/loader';
import QuickAddList from './QuickAddList';
const projectInCollection = (project, collection) =>
collection.items.find(item => item.projectId === project.id) != null;
class CollectionList extends React.Component {
constructor(props) {
super(props);
if (props.projectId) {
props.getProject(props.projectId);
}
this.props.getCollections(this.props.username);
this.state = {
hasLoadedData: false,
};
}
componentDidUpdate(prevProps) {
if (prevProps.loading === true && this.props.loading === false) {
// eslint-disable-next-line react/no-did-update-set-state
this.setState({
hasLoadedData: true,
});
}
}
getTitle() {
if (this.props.username === this.props.user.username) {
return 'p5.js Web Editor | My collections';
}
return `p5.js Web Editor | ${this.props.username}'s collections`;
}
handleCollectionAdd = (collection) => {
this.props.addToCollection(collection.id, this.props.project.id);
}
handleCollectionRemove = (collection) => {
this.props.removeFromCollection(collection.id, this.props.project.id);
}
render() {
const { collections, project } = this.props;
const hasCollections = collections.length > 0;
const collectionWithSketchStatus = collections.map(collection => ({
...collection,
url: `/${collection.owner.username}/collections/${collection.id}`,
isAdded: projectInCollection(project, collection),
}));
let content = null;
if (this.props.loading && !this.state.hasLoadedData) {
content = <Loader />;
} else if (hasCollections) {
content = (
<QuickAddList
items={collectionWithSketchStatus}
onAdd={this.handleCollectionAdd}
onRemove={this.handleCollectionRemove}
/>
);
} else {
content = 'No collections';
}
return (
<div className="collection-add-sketch">
<div className="quick-add-wrapper">
<Helmet>
<title>{this.getTitle()}</title>
</Helmet>
{content}
</div>
</div>
);
}
}
const ProjectShape = PropTypes.shape({
id: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
createdAt: PropTypes.string.isRequired,
updatedAt: PropTypes.string.isRequired,
user: PropTypes.shape({
username: PropTypes.string.isRequired
}).isRequired,
});
const ItemsShape = PropTypes.shape({
createdAt: PropTypes.string.isRequired,
updatedAt: PropTypes.string.isRequired,
project: ProjectShape
});
CollectionList.propTypes = {
user: PropTypes.shape({
username: PropTypes.string,
authenticated: PropTypes.bool.isRequired
}).isRequired,
projectId: PropTypes.string.isRequired,
getCollections: PropTypes.func.isRequired,
getProject: PropTypes.func.isRequired,
addToCollection: PropTypes.func.isRequired,
removeFromCollection: PropTypes.func.isRequired,
collections: PropTypes.arrayOf(PropTypes.shape({
id: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
description: PropTypes.string,
createdAt: PropTypes.string.isRequired,
updatedAt: PropTypes.string.isRequired,
items: PropTypes.arrayOf(ItemsShape),
})).isRequired,
username: PropTypes.string,
loading: PropTypes.bool.isRequired,
project: PropTypes.shape({
id: PropTypes.string,
owner: PropTypes.shape({
id: PropTypes.string
})
})
};
CollectionList.defaultProps = {
project: {
id: undefined,
owner: undefined
},
username: undefined
};
function mapStateToProps(state, ownProps) {
return {
user: state.user,
collections: getSortedCollections(state),
sorting: state.sorting,
loading: state.loading,
project: ownProps.project || state.project,
projectId: ownProps && ownProps.params ? ownProps.prams.project_id : null,
};
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(
Object.assign({}, CollectionsActions, ProjectsActions, ProjectActions, ToastActions, SortingActions),
dispatch
);
}
export default connect(mapStateToProps, mapDispatchToProps)(CollectionList);