Skip to content

Commit d585443

Browse files
committed
Convert AddToCollectionSketchList to a function component and connect to Redux.
1 parent b5ecd60 commit d585443

File tree

4 files changed

+61
-138
lines changed

4 files changed

+61
-138
lines changed

client/modules/IDE/actions/projects.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,9 @@ export function getProjects(username) {
2222
dispatch(stopLoader());
2323
})
2424
.catch((error) => {
25-
const { response } = error;
2625
dispatch({
2726
type: ActionTypes.ERROR,
28-
error: response.data
27+
error: error?.response?.data
2928
});
3029
dispatch(stopLoader());
3130
});
Lines changed: 60 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -1,161 +1,87 @@
11
import PropTypes from 'prop-types';
2-
import React from 'react';
2+
import React, { useEffect, useState } from 'react';
33
import { Helmet } from 'react-helmet';
4-
import { connect } from 'react-redux';
5-
import { bindActionCreators } from 'redux';
6-
import { withTranslation } from 'react-i18next';
7-
// import find from 'lodash/find';
8-
import * as ProjectsActions from '../actions/projects';
9-
import * as CollectionsActions from '../actions/collections';
10-
import * as ToastActions from '../actions/toast';
11-
import * as SortingActions from '../actions/sorting';
4+
import { useDispatch, useSelector } from 'react-redux';
5+
import { useTranslation } from 'react-i18next';
6+
import { addToCollection, removeFromCollection } from '../actions/collections';
7+
import { getProjects } from '../actions/projects';
128
import getSortedSketches from '../selectors/projects';
139
import Loader from '../../App/components/loader';
1410
import QuickAddList from './QuickAddList';
1511

16-
class SketchList extends React.Component {
17-
constructor(props) {
18-
super(props);
19-
this.props.getProjects(this.props.username);
12+
const AddToCollectionSketchList = ({ collection }) => {
13+
const { t } = useTranslation();
2014

21-
this.state = {
22-
isInitialDataLoad: true
23-
};
24-
}
15+
const dispatch = useDispatch();
2516

26-
componentWillReceiveProps(nextProps) {
27-
if (
28-
this.props.sketches !== nextProps.sketches &&
29-
Array.isArray(nextProps.sketches)
30-
) {
31-
this.setState({
32-
isInitialDataLoad: false
33-
});
34-
}
35-
}
36-
37-
getSketchesTitle() {
38-
if (this.props.username === this.props.user.username) {
39-
return this.props.t('AddToCollectionSketchList.Title');
40-
}
41-
return this.props.t('AddToCollectionSketchList.AnothersTitle', {
42-
anotheruser: this.props.username
43-
});
44-
}
17+
const username = useSelector((state) => state.user.username);
4518

46-
handleCollectionAdd = (sketch) => {
47-
this.props.addToCollection(this.props.collection.id, sketch.id);
48-
};
19+
const sketches = useSelector(getSortedSketches);
4920

50-
handleCollectionRemove = (sketch) => {
51-
this.props.removeFromCollection(this.props.collection.id, sketch.id);
52-
};
21+
// TODO: improve loading state
22+
const loading = useSelector((state) => state.loading);
23+
const [hasLoadedData, setHasLoadedData] = useState(false);
24+
const showLoader = loading && !hasLoadedData;
5325

54-
inCollection = (sketch) =>
55-
this.props.collection.items.find((item) =>
56-
item.isDeleted ? false : item.project.id === sketch.id
57-
) != null;
26+
useEffect(() => {
27+
dispatch(getProjects(username)).then(() => setHasLoadedData(true));
28+
}, [dispatch, username]);
5829

59-
render() {
60-
const hasSketches = this.props.sketches.length > 0;
61-
const sketchesWithAddedStatus = this.props.sketches.map((sketch) => ({
62-
...sketch,
63-
isAdded: this.inCollection(sketch),
64-
url: `/${this.props.username}/sketches/${sketch.id}`
65-
}));
30+
const handleCollectionAdd = (sketch) => {
31+
dispatch(addToCollection(collection.id, sketch.id));
32+
};
6633

67-
let content = null;
34+
const handleCollectionRemove = (sketch) => {
35+
dispatch(removeFromCollection(collection.id, sketch.id));
36+
};
6837

69-
if (this.props.loading && this.state.isInitialDataLoad) {
70-
content = <Loader />;
71-
} else if (hasSketches) {
72-
content = (
73-
<QuickAddList
74-
items={sketchesWithAddedStatus}
75-
onAdd={this.handleCollectionAdd}
76-
onRemove={this.handleCollectionRemove}
77-
/>
78-
);
79-
} else {
80-
content = this.props.t('AddToCollectionSketchList.NoCollections');
38+
const sketchesWithAddedStatus = sketches.map((sketch) => ({
39+
...sketch,
40+
url: `/${username}/sketches/${sketch.id}`,
41+
isAdded: collection.items.some(
42+
(item) => item.projectId === sketch.id && !item.isDeleted
43+
)
44+
}));
45+
46+
const getContent = () => {
47+
if (showLoader) {
48+
return <Loader />;
49+
} else if (sketches.length === 0) {
50+
// TODO: shouldn't it be NoSketches? -Linda
51+
return t('AddToCollectionSketchList.NoCollections');
8152
}
82-
8353
return (
84-
<div className="collection-add-sketch">
85-
<div className="quick-add-wrapper">
86-
<Helmet>
87-
<title>{this.getSketchesTitle()}</title>
88-
</Helmet>
89-
{content}
90-
</div>
91-
</div>
54+
<QuickAddList
55+
items={sketchesWithAddedStatus}
56+
onAdd={handleCollectionAdd}
57+
onRemove={handleCollectionRemove}
58+
/>
9259
);
93-
}
94-
}
60+
};
9561

96-
SketchList.propTypes = {
97-
user: PropTypes.shape({
98-
username: PropTypes.string,
99-
authenticated: PropTypes.bool.isRequired
100-
}).isRequired,
101-
getProjects: PropTypes.func.isRequired,
102-
sketches: PropTypes.arrayOf(
103-
PropTypes.shape({
104-
id: PropTypes.string.isRequired,
105-
name: PropTypes.string.isRequired,
106-
createdAt: PropTypes.string.isRequired,
107-
updatedAt: PropTypes.string.isRequired
108-
})
109-
).isRequired,
62+
return (
63+
<div className="collection-add-sketch">
64+
<div className="quick-add-wrapper">
65+
<Helmet>
66+
<title>{t('AddToCollectionSketchList.Title')}</title>
67+
</Helmet>
68+
{getContent()}
69+
</div>
70+
</div>
71+
);
72+
};
73+
74+
AddToCollectionSketchList.propTypes = {
11075
collection: PropTypes.shape({
11176
id: PropTypes.string.isRequired,
11277
name: PropTypes.string.isRequired,
11378
items: PropTypes.arrayOf(
11479
PropTypes.shape({
115-
project: PropTypes.shape({
116-
id: PropTypes.string.isRequired
117-
})
80+
projectId: PropTypes.string.isRequired,
81+
isDeleted: PropTypes.bool
11882
})
11983
)
120-
}).isRequired,
121-
username: PropTypes.string,
122-
loading: PropTypes.bool.isRequired,
123-
sorting: PropTypes.shape({
124-
field: PropTypes.string.isRequired,
125-
direction: PropTypes.string.isRequired
126-
}).isRequired,
127-
addToCollection: PropTypes.func.isRequired,
128-
removeFromCollection: PropTypes.func.isRequired,
129-
t: PropTypes.func.isRequired
130-
};
131-
132-
SketchList.defaultProps = {
133-
username: undefined
84+
}).isRequired
13485
};
13586

136-
function mapStateToProps(state) {
137-
return {
138-
user: state.user,
139-
sketches: getSortedSketches(state),
140-
sorting: state.sorting,
141-
loading: state.loading,
142-
project: state.project
143-
};
144-
}
145-
146-
function mapDispatchToProps(dispatch) {
147-
return bindActionCreators(
148-
Object.assign(
149-
{},
150-
ProjectsActions,
151-
CollectionsActions,
152-
ToastActions,
153-
SortingActions
154-
),
155-
dispatch
156-
);
157-
}
158-
159-
export default withTranslation()(
160-
connect(mapStateToProps, mapDispatchToProps)(SketchList)
161-
);
87+
export default AddToCollectionSketchList;

client/modules/IDE/components/CollectionList/CollectionList.jsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,6 @@ class CollectionList extends React.Component {
227227
isFixedHeight
228228
>
229229
<AddToCollectionSketchList
230-
username={this.props.username}
231230
collection={find(this.props.collections, {
232231
id: this.state.addingSketchesToCollectionId
233232
})}

client/modules/User/components/Collection.jsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,6 @@ class Collection extends React.Component {
473473
isFixedHeight
474474
>
475475
<AddToCollectionSketchList
476-
username={this.props.username}
477476
collection={this.props.collection}
478477
/>
479478
</Overlay>

0 commit comments

Comments
 (0)