New simplified sketch list when adding from Collection view
This commit is contained in:
parent
08fd6b826d
commit
ad13684fe3
6 changed files with 161 additions and 28 deletions
|
@ -1,10 +1,8 @@
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Helmet } from 'react-helmet';
|
import { Helmet } from 'react-helmet';
|
||||||
import InlineSVG from 'react-inlinesvg';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { bindActionCreators } from 'redux';
|
import { bindActionCreators } from 'redux';
|
||||||
import classNames from 'classnames';
|
|
||||||
|
|
||||||
import * as ProjectActions from '../actions/project';
|
import * as ProjectActions from '../actions/project';
|
||||||
import * as ProjectsActions from '../actions/projects';
|
import * as ProjectsActions from '../actions/projects';
|
||||||
|
@ -13,7 +11,7 @@ import * as ToastActions from '../actions/toast';
|
||||||
import * as SortingActions from '../actions/sorting';
|
import * as SortingActions from '../actions/sorting';
|
||||||
import getSortedCollections from '../selectors/collections';
|
import getSortedCollections from '../selectors/collections';
|
||||||
import Loader from '../../App/components/loader';
|
import Loader from '../../App/components/loader';
|
||||||
import QuickAddList from './QuickAddList/QuickAddList';
|
import QuickAddList from './QuickAddList';
|
||||||
|
|
||||||
const projectInCollection = (project, collection) => collection.items.find(item => item.project.id === project.id) != null;
|
const projectInCollection = (project, collection) => collection.items.find(item => item.project.id === project.id) != null;
|
||||||
|
|
||||||
|
@ -56,14 +54,6 @@ class CollectionList extends React.Component {
|
||||||
this.props.removeFromCollection(collection.id, this.props.project.id);
|
this.props.removeFromCollection(collection.id, this.props.project.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleAddRemove = (collection) => {
|
|
||||||
if (projectInCollection(this.props.project, collection)) {
|
|
||||||
this.handleCollectionRemove(collection);
|
|
||||||
} else {
|
|
||||||
this.handleCollectionAdd(collection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const username = this.props.username !== undefined ? this.props.username : this.props.user.username;
|
const username = this.props.username !== undefined ? this.props.username : this.props.user.username;
|
||||||
const { collections, project } = this.props;
|
const { collections, project } = this.props;
|
||||||
|
@ -79,13 +69,13 @@ class CollectionList extends React.Component {
|
||||||
if (this.props.loading && !this.state.hasLoadedData) {
|
if (this.props.loading && !this.state.hasLoadedData) {
|
||||||
content = <Loader />;
|
content = <Loader />;
|
||||||
} else if (hasCollections) {
|
} else if (hasCollections) {
|
||||||
content = <QuickAddList items={collectionWithSketchStatus} onSelect={this.handleAddRemove} />;
|
content = <QuickAddList items={collectionWithSketchStatus} onAdd={this.handleCollectionAdd} onRemove={this.handleCollectionRemove} />;
|
||||||
} else {
|
} else {
|
||||||
content = 'No collections';
|
content = 'No collections';
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="sketches-table-container">
|
<div className="quick-add--has-padding">
|
||||||
<Helmet>
|
<Helmet>
|
||||||
<title>{this.getTitle()}</title>
|
<title>{this.getTitle()}</title>
|
||||||
</Helmet>
|
</Helmet>
|
||||||
|
@ -154,7 +144,7 @@ function mapStateToProps(state, ownProps) {
|
||||||
collections: getSortedCollections(state),
|
collections: getSortedCollections(state),
|
||||||
sorting: state.sorting,
|
sorting: state.sorting,
|
||||||
loading: state.loading,
|
loading: state.loading,
|
||||||
project: state.project,
|
project: ownProps.project || state.project,
|
||||||
projectId: ownProps && ownProps.params ? ownProps.prams.project_id : null,
|
projectId: ownProps && ownProps.params ? ownProps.prams.project_id : null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
130
client/modules/IDE/components/AddToCollectionSketchList.jsx
Normal file
130
client/modules/IDE/components/AddToCollectionSketchList.jsx
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import React from 'react';
|
||||||
|
import { Helmet } from 'react-helmet';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { bindActionCreators } from 'redux';
|
||||||
|
// import find from 'lodash/find';
|
||||||
|
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 getSortedSketches from '../selectors/projects';
|
||||||
|
import Loader from '../../App/components/loader';
|
||||||
|
import QuickAddList from './QuickAddList';
|
||||||
|
|
||||||
|
class SketchList extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.props.getProjects(this.props.username);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
isInitialDataLoad: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps(nextProps) {
|
||||||
|
if (this.props.sketches !== nextProps.sketches && Array.isArray(nextProps.sketches)) {
|
||||||
|
this.setState({
|
||||||
|
isInitialDataLoad: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getSketchesTitle() {
|
||||||
|
if (this.props.username === this.props.user.username) {
|
||||||
|
return 'p5.js Web Editor | My sketches';
|
||||||
|
}
|
||||||
|
return `p5.js Web Editor | ${this.props.username}'s sketches`;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleCollectionAdd = (sketch) => {
|
||||||
|
this.props.addToCollection(this.props.collection.id, sketch.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleCollectionRemove = (sketch) => {
|
||||||
|
this.props.removeFromCollection(this.props.collection.id, sketch.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
inCollection = sketch => this.props.collection.items.find(item => item.project.id === sketch.id) != null
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const hasSketches = this.props.sketches.length > 0;
|
||||||
|
const sketchesWithAddedStatus = this.props.sketches.map(sketch => ({
|
||||||
|
...sketch,
|
||||||
|
isAdded: this.inCollection(sketch),
|
||||||
|
}));
|
||||||
|
|
||||||
|
let content = null;
|
||||||
|
|
||||||
|
if (this.props.loading && this.state.isInitialDataLoad) {
|
||||||
|
content = <Loader />;
|
||||||
|
} else if (hasSketches) {
|
||||||
|
content = <QuickAddList items={sketchesWithAddedStatus} onAdd={this.handleCollectionAdd} onRemove={this.handleCollectionRemove} />;
|
||||||
|
} else {
|
||||||
|
content = 'No collections';
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Helmet>
|
||||||
|
<title>{this.getSketchesTitle()}</title>
|
||||||
|
</Helmet>
|
||||||
|
{content}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SketchList.propTypes = {
|
||||||
|
user: PropTypes.shape({
|
||||||
|
username: PropTypes.string,
|
||||||
|
authenticated: PropTypes.bool.isRequired
|
||||||
|
}).isRequired,
|
||||||
|
getProjects: PropTypes.func.isRequired,
|
||||||
|
sketches: PropTypes.arrayOf(PropTypes.shape({
|
||||||
|
id: PropTypes.string.isRequired,
|
||||||
|
name: PropTypes.string.isRequired,
|
||||||
|
createdAt: PropTypes.string.isRequired,
|
||||||
|
updatedAt: PropTypes.string.isRequired
|
||||||
|
})).isRequired,
|
||||||
|
collection: PropTypes.shape({
|
||||||
|
id: PropTypes.string.isRequired,
|
||||||
|
name: PropTypes.string.isRequired,
|
||||||
|
items: PropTypes.arrayOf(PropTypes.shape({
|
||||||
|
project: PropTypes.shape({
|
||||||
|
id: PropTypes.string.isRequired,
|
||||||
|
}),
|
||||||
|
})),
|
||||||
|
}).isRequired,
|
||||||
|
username: PropTypes.string,
|
||||||
|
loading: PropTypes.bool.isRequired,
|
||||||
|
sorting: PropTypes.shape({
|
||||||
|
field: PropTypes.string.isRequired,
|
||||||
|
direction: PropTypes.string.isRequired
|
||||||
|
}).isRequired,
|
||||||
|
addToCollection: PropTypes.func.isRequired,
|
||||||
|
removeFromCollection: PropTypes.func.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
SketchList.defaultProps = {
|
||||||
|
username: undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
function mapStateToProps(state) {
|
||||||
|
return {
|
||||||
|
user: state.user,
|
||||||
|
sketches: getSortedSketches(state),
|
||||||
|
sorting: state.sorting,
|
||||||
|
loading: state.loading,
|
||||||
|
project: state.project
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapDispatchToProps(dispatch) {
|
||||||
|
return bindActionCreators(
|
||||||
|
Object.assign({}, ProjectsActions, CollectionsActions, ToastActions, SortingActions),
|
||||||
|
dispatch
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(SketchList);
|
|
@ -27,20 +27,33 @@ Item.propTypes = {
|
||||||
onSelect: PropTypes.func.isRequired,
|
onSelect: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
const QuickAddList = ({ items, onSelect }) => (
|
const QuickAddList = ({
|
||||||
<ul className="quick-add">{items.map(item => (<Item
|
items, onAdd, onRemove
|
||||||
key={item.id}
|
}) => {
|
||||||
{...item}
|
const handleAction = (item) => {
|
||||||
onSelect={
|
if (item.isAdded) {
|
||||||
() => onSelect(item)
|
onRemove(item);
|
||||||
|
} else {
|
||||||
|
onAdd(item);
|
||||||
}
|
}
|
||||||
/>))}
|
};
|
||||||
</ul>
|
|
||||||
);
|
return (
|
||||||
|
<ul className="quick-add">{items.map(item => (<Item
|
||||||
|
key={item.id}
|
||||||
|
{...item}
|
||||||
|
onSelect={
|
||||||
|
() => handleAction(item)
|
||||||
|
}
|
||||||
|
/>))}
|
||||||
|
</ul>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
QuickAddList.propTypes = {
|
QuickAddList.propTypes = {
|
||||||
items: PropTypes.arrayOf(ItemType).isRequired,
|
items: PropTypes.arrayOf(ItemType).isRequired,
|
||||||
onSelect: PropTypes.func.isRequired,
|
onAdd: PropTypes.func.isRequired,
|
||||||
|
onRemove: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default QuickAddList;
|
export default QuickAddList;
|
||||||
|
|
|
@ -17,7 +17,7 @@ import { getCollection } from '../../IDE/selectors/collections';
|
||||||
import Loader from '../../App/components/loader';
|
import Loader from '../../App/components/loader';
|
||||||
import EditableInput from '../../IDE/components/EditableInput';
|
import EditableInput from '../../IDE/components/EditableInput';
|
||||||
import Overlay from '../../App/components/Overlay';
|
import Overlay from '../../App/components/Overlay';
|
||||||
import SketchList from '../../IDE/components/SketchList';
|
import SketchList from '../../IDE/components/AddToCollectionSketchList';
|
||||||
import CopyableInput from '../../IDE/components/CopyableInput';
|
import CopyableInput from '../../IDE/components/CopyableInput';
|
||||||
import SketchSearchbar from '../../IDE/components/Searchbar';
|
import SketchSearchbar from '../../IDE/components/Searchbar';
|
||||||
|
|
||||||
|
@ -470,7 +470,7 @@ class Collection extends React.Component {
|
||||||
this.state.isAddingSketches && (
|
this.state.isAddingSketches && (
|
||||||
<Overlay title="Add sketches" actions={<SketchSearchbar />} closeOverlay={this.hideAddSketches}>
|
<Overlay title="Add sketches" actions={<SketchSearchbar />} closeOverlay={this.hideAddSketches}>
|
||||||
<div className="collection-add-sketch">
|
<div className="collection-add-sketch">
|
||||||
<SketchList username={this.props.username} addMode collection={this.props.collection} />
|
<SketchList username={this.props.username} collection={this.props.collection} />
|
||||||
</div>
|
</div>
|
||||||
</Overlay>
|
</Overlay>
|
||||||
)
|
)
|
||||||
|
|
|
@ -84,7 +84,6 @@
|
||||||
|
|
||||||
.collection-add-sketch {
|
.collection-add-sketch {
|
||||||
min-width: #{800 / $base-font-size}rem;
|
min-width: #{800 / $base-font-size}rem;
|
||||||
padding: #{24 / $base-font-size}rem;
|
|
||||||
overflow: scroll;
|
overflow: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
.quick-add {
|
.quick-add {
|
||||||
|
width: auto;
|
||||||
|
min-width: #{600 / $base-font-size}rem;
|
||||||
padding: #{24 / $base-font-size}rem;
|
padding: #{24 / $base-font-size}rem;
|
||||||
width: #{600 / $base-font-size}rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.quick-add__item {
|
.quick-add__item {
|
||||||
|
|
Loading…
Reference in a new issue