From d585443b8086aa236aa2bed843a0249c1d5b9be9 Mon Sep 17 00:00:00 2001 From: Linda Paiste Date: Mon, 7 Aug 2023 17:26:59 -0500 Subject: [PATCH] Convert `AddToCollectionSketchList` to a function component and connect to Redux. --- client/modules/IDE/actions/projects.js | 3 +- .../components/AddToCollectionSketchList.jsx | 194 ++++++------------ .../CollectionList/CollectionList.jsx | 1 - client/modules/User/components/Collection.jsx | 1 - 4 files changed, 61 insertions(+), 138 deletions(-) diff --git a/client/modules/IDE/actions/projects.js b/client/modules/IDE/actions/projects.js index 4072429af4..eb9984cf54 100644 --- a/client/modules/IDE/actions/projects.js +++ b/client/modules/IDE/actions/projects.js @@ -22,10 +22,9 @@ export function getProjects(username) { dispatch(stopLoader()); }) .catch((error) => { - const { response } = error; dispatch({ type: ActionTypes.ERROR, - error: response.data + error: error?.response?.data }); dispatch(stopLoader()); }); diff --git a/client/modules/IDE/components/AddToCollectionSketchList.jsx b/client/modules/IDE/components/AddToCollectionSketchList.jsx index e42aff8d60..41ae71de5a 100644 --- a/client/modules/IDE/components/AddToCollectionSketchList.jsx +++ b/client/modules/IDE/components/AddToCollectionSketchList.jsx @@ -1,161 +1,87 @@ import PropTypes from 'prop-types'; -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { Helmet } from 'react-helmet'; -import { connect } from 'react-redux'; -import { bindActionCreators } from 'redux'; -import { withTranslation } from 'react-i18next'; -// 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 { useDispatch, useSelector } from 'react-redux'; +import { useTranslation } from 'react-i18next'; +import { addToCollection, removeFromCollection } from '../actions/collections'; +import { getProjects } from '../actions/projects'; 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); +const AddToCollectionSketchList = ({ collection }) => { + const { t } = useTranslation(); - this.state = { - isInitialDataLoad: true - }; - } + const dispatch = useDispatch(); - 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 this.props.t('AddToCollectionSketchList.Title'); - } - return this.props.t('AddToCollectionSketchList.AnothersTitle', { - anotheruser: this.props.username - }); - } + const username = useSelector((state) => state.user.username); - handleCollectionAdd = (sketch) => { - this.props.addToCollection(this.props.collection.id, sketch.id); - }; + const sketches = useSelector(getSortedSketches); - handleCollectionRemove = (sketch) => { - this.props.removeFromCollection(this.props.collection.id, sketch.id); - }; + // TODO: improve loading state + const loading = useSelector((state) => state.loading); + const [hasLoadedData, setHasLoadedData] = useState(false); + const showLoader = loading && !hasLoadedData; - inCollection = (sketch) => - this.props.collection.items.find((item) => - item.isDeleted ? false : item.project.id === sketch.id - ) != null; + useEffect(() => { + dispatch(getProjects(username)).then(() => setHasLoadedData(true)); + }, [dispatch, username]); - render() { - const hasSketches = this.props.sketches.length > 0; - const sketchesWithAddedStatus = this.props.sketches.map((sketch) => ({ - ...sketch, - isAdded: this.inCollection(sketch), - url: `/${this.props.username}/sketches/${sketch.id}` - })); + const handleCollectionAdd = (sketch) => { + dispatch(addToCollection(collection.id, sketch.id)); + }; - let content = null; + const handleCollectionRemove = (sketch) => { + dispatch(removeFromCollection(collection.id, sketch.id)); + }; - if (this.props.loading && this.state.isInitialDataLoad) { - content = ; - } else if (hasSketches) { - content = ( - - ); - } else { - content = this.props.t('AddToCollectionSketchList.NoCollections'); + const sketchesWithAddedStatus = sketches.map((sketch) => ({ + ...sketch, + url: `/${username}/sketches/${sketch.id}`, + isAdded: collection.items.some( + (item) => item.projectId === sketch.id && !item.isDeleted + ) + })); + + const getContent = () => { + if (showLoader) { + return ; + } else if (sketches.length === 0) { + // TODO: shouldn't it be NoSketches? -Linda + return t('AddToCollectionSketchList.NoCollections'); } - return ( -
-
- - {this.getSketchesTitle()} - - {content} -
-
+ ); - } -} + }; -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, + return ( +
+
+ + {t('AddToCollectionSketchList.Title')} + + {getContent()} +
+
+ ); +}; + +AddToCollectionSketchList.propTypes = { collection: PropTypes.shape({ id: PropTypes.string.isRequired, name: PropTypes.string.isRequired, items: PropTypes.arrayOf( PropTypes.shape({ - project: PropTypes.shape({ - id: PropTypes.string.isRequired - }) + projectId: PropTypes.string.isRequired, + isDeleted: PropTypes.bool }) ) - }).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, - t: PropTypes.func.isRequired -}; - -SketchList.defaultProps = { - username: undefined + }).isRequired }; -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 withTranslation()( - connect(mapStateToProps, mapDispatchToProps)(SketchList) -); +export default AddToCollectionSketchList; diff --git a/client/modules/IDE/components/CollectionList/CollectionList.jsx b/client/modules/IDE/components/CollectionList/CollectionList.jsx index 646b9824b5..8b16a4898f 100644 --- a/client/modules/IDE/components/CollectionList/CollectionList.jsx +++ b/client/modules/IDE/components/CollectionList/CollectionList.jsx @@ -227,7 +227,6 @@ class CollectionList extends React.Component { isFixedHeight >