diff --git a/client/modules/IDE/actions/collections.js b/client/modules/IDE/actions/collections.js index 24b1ae3797..e8bda9623f 100644 --- a/client/modules/IDE/actions/collections.js +++ b/client/modules/IDE/actions/collections.js @@ -6,7 +6,6 @@ import { setToastText, showToast } from './toast'; const TOAST_DISPLAY_TIME_MS = 1500; -// eslint-disable-next-line export function getCollections(username) { return (dispatch) => { dispatch(startLoader()); @@ -16,8 +15,7 @@ export function getCollections(username) { } else { url = '/collections'; } - console.log(url); - apiClient + return apiClient .get(url) .then((response) => { dispatch({ diff --git a/client/modules/IDE/components/AddToCollectionList.jsx b/client/modules/IDE/components/AddToCollectionList.jsx index 0cb4768c3e..ecb020ce6f 100644 --- a/client/modules/IDE/components/AddToCollectionList.jsx +++ b/client/modules/IDE/components/AddToCollectionList.jsx @@ -1,23 +1,19 @@ 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 { useTranslation } from 'react-i18next'; +import { useDispatch, useSelector } from 'react-redux'; import styled from 'styled-components'; -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 { + addToCollection, + getCollections, + removeFromCollection +} from '../actions/collections'; +import getSortedCollections from '../selectors/collections'; import QuickAddList from './QuickAddList'; import { remSize } from '../../../theme'; -const projectInCollection = (project, collection) => - collection.items.find((item) => item.projectId === project.id) != null; - export const CollectionAddSketchWrapper = styled.div` width: ${remSize(600)}; max-width: 100%; @@ -31,166 +27,67 @@ export const QuickAddWrapper = styled.div` height: 100%; `; -class CollectionList extends React.Component { - constructor(props) { - super(props); +const AddToCollectionList = ({ projectId }) => { + const { t } = useTranslation(); - if (props.projectId) { - props.getProject(props.projectId); - } + const dispatch = useDispatch(); - this.props.getCollections(this.props.user.username); + const username = useSelector((state) => state.user.username); - this.state = { - hasLoadedData: false - }; - } + const collections = useSelector(getSortedCollections); - componentDidUpdate(prevProps) { - if (prevProps.loading === true && this.props.loading === false) { - // eslint-disable-next-line react/no-did-update-set-state - this.setState({ - hasLoadedData: true - }); - } - } + // TODO: improve loading state + const loading = useSelector((state) => state.loading); + const [hasLoadedData, setHasLoadedData] = useState(false); + const showLoader = loading && !hasLoadedData; - getTitle() { - if (this.props.username === this.props.user.username) { - return this.props.t('AddToCollectionList.Title'); - } - return this.props.t('AddToCollectionList.AnothersTitle', { - anotheruser: this.props.username - }); - } + useEffect(() => { + dispatch(getCollections(username)).then(() => setHasLoadedData(true)); + }, [dispatch, username]); - handleCollectionAdd = (collection) => { - this.props.addToCollection(collection.id, this.props.project.id); + const handleCollectionAdd = (collection) => { + dispatch(addToCollection(collection.id, projectId)); }; - handleCollectionRemove = (collection) => { - this.props.removeFromCollection(collection.id, this.props.project.id); + const handleCollectionRemove = (collection) => { + dispatch(removeFromCollection(collection.id, projectId)); }; - 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 = ; - } else if (hasCollections) { - content = ( - - ); - } else { - content = this.props.t('AddToCollectionList.Empty'); + const collectionWithSketchStatus = collections.map((collection) => ({ + ...collection, + url: `/${collection.owner.username}/collections/${collection.id}`, + isAdded: collection.items.some((item) => item.projectId === projectId) + })); + + const getContent = () => { + if (showLoader) { + return ; + } else if (collections.length === 0) { + return t('AddToCollectionList.Empty'); } - return ( - - - - {this.getTitle()} - - {content} - - + ); - } -} - -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 - }) - }), - t: PropTypes.func.isRequired + return ( + + + + {t('AddToCollectionList.Title')} + + {getContent()} + + + ); }; -CollectionList.defaultProps = { - project: { - id: undefined, - owner: undefined - }, - username: undefined +AddToCollectionList.propTypes = { + projectId: PropTypes.string.isRequired }; -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 withTranslation()( - connect(mapStateToProps, mapDispatchToProps)(CollectionList) -); +export default AddToCollectionList; diff --git a/client/modules/IDE/components/IDEOverlays.jsx b/client/modules/IDE/components/IDEOverlays.jsx index 6dba0e76f5..92f8256ae8 100644 --- a/client/modules/IDE/components/IDEOverlays.jsx +++ b/client/modules/IDE/components/IDEOverlays.jsx @@ -1,7 +1,7 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; import { useDispatch, useSelector } from 'react-redux'; -import { useLocation, useParams } from 'react-router-dom'; +import { useLocation } from 'react-router-dom'; import Overlay from '../../App/components/Overlay'; import { closeKeyboardShortcutModal, @@ -25,7 +25,6 @@ export default function IDEOverlays() { const { t } = useTranslation(); const dispatch = useDispatch(); const location = useLocation(); - const params = useParams(); const { modalIsVisible, @@ -79,8 +78,7 @@ export default function IDEOverlays() { isFixedHeight > )} diff --git a/client/modules/IDE/components/SketchList.jsx b/client/modules/IDE/components/SketchList.jsx index 85d3030d61..2237227766 100644 --- a/client/modules/IDE/components/SketchList.jsx +++ b/client/modules/IDE/components/SketchList.jsx @@ -418,9 +418,7 @@ class SketchList extends React.Component { } > )}