- |
---|
+ {t('Collection.NoSketches')} +
+ )} + {hasCollectionItems && ( ++ |
---|
diff --git a/client/modules/User/components/Collection.jsx b/client/modules/User/components/Collection.jsx
index 939b2b851f..6f6ec17dae 100644
--- a/client/modules/User/components/Collection.jsx
+++ b/client/modules/User/components/Collection.jsx
@@ -1,18 +1,19 @@
import PropTypes from 'prop-types';
-import React from 'react';
+import React, { useEffect, useMemo } from 'react';
import { Helmet } from 'react-helmet';
-import { connect } from 'react-redux';
+import { useDispatch, useSelector } from 'react-redux';
import { Link } from 'react-router-dom';
-import { bindActionCreators } from 'redux';
-import { useTranslation, withTranslation } from 'react-i18next';
+import { useTranslation } from 'react-i18next';
import classNames from 'classnames';
-
-import * as ProjectActions from '../../IDE/actions/project';
-import * as ProjectsActions from '../../IDE/actions/projects';
-import * as CollectionsActions from '../../IDE/actions/collections';
-import * as ToastActions from '../../IDE/actions/toast';
+import {
+ getCollections,
+ removeFromCollection
+} from '../../IDE/actions/collections';
+import {
+ resetSorting,
+ toggleDirectionForField
+} from '../../IDE/actions/sorting';
import * as SortingActions from '../../IDE/actions/sorting';
-import * as IdeActions from '../../IDE/actions/ide';
import { getCollection } from '../../IDE/selectors/collections';
import Loader from '../../App/components/loader';
import dates from '../../../utils/formatDate';
@@ -22,14 +23,11 @@ import ArrowDownIcon from '../../../images/sort-arrow-down.svg';
import RemoveIcon from '../../../images/close.svg';
import CollectionMetadata from './CollectionMetadata';
-const CollectionItemRowBase = ({
- collection,
- item,
- isOwner,
- removeFromCollection
-}) => {
+const CollectionItemRow = ({ collection, item, isOwner }) => {
const { t } = useTranslation();
+ const dispatch = useDispatch();
+
const projectIsDeleted = item.isDeleted;
const handleSketchRemove = () => {
@@ -40,7 +38,7 @@ const CollectionItemRowBase = ({
t('Collection.DeleteFromCollection', { name_sketch: name })
)
) {
- removeFromCollection(collection.id, item.projectId);
+ dispatch(removeFromCollection(collection.id, item.projectId));
}
};
@@ -78,7 +76,7 @@ const CollectionItemRowBase = ({
);
};
-CollectionItemRowBase.propTypes = {
+CollectionItemRow.propTypes = {
collection: PropTypes.shape({
id: PropTypes.string.isRequired,
name: PropTypes.string.isRequired
@@ -95,139 +93,89 @@ CollectionItemRowBase.propTypes = {
})
}).isRequired
}).isRequired,
- isOwner: PropTypes.bool.isRequired,
- user: PropTypes.shape({
- username: PropTypes.string,
- authenticated: PropTypes.bool.isRequired
- }).isRequired,
- removeFromCollection: PropTypes.func.isRequired
+ isOwner: PropTypes.bool.isRequired
};
-function mapDispatchToPropsSketchListRow(dispatch) {
- return bindActionCreators(
- Object.assign({}, CollectionsActions, ProjectActions, IdeActions),
- dispatch
- );
-}
+const Collection = ({ username, collectionId }) => {
+ const { t } = useTranslation();
+ const dispatch = useDispatch();
-const CollectionItemRow = connect(
- null,
- mapDispatchToPropsSketchListRow
-)(CollectionItemRowBase);
+ const collection = useSelector((state) => getCollection(state, collectionId));
-class Collection extends React.Component {
- constructor(props) {
- super(props);
- this.props.getCollections(this.props.username);
- this.props.resetSorting();
- this._renderFieldHeader = this._renderFieldHeader.bind(this);
- }
+ const hasCollectionItems = collection?.items.length > 0;
+ const hasZeroItems = collection?.items.length === 0;
- getTitle() {
- if (this.hasCollection()) {
- return `${this.props.t('Common.SiteName')} | ${this.getCollectionName()}`;
- }
- if (this.props.username === this.props.user.username) {
- return this.props.t('Collection.Title');
- }
- return this.props.t('Collection.AnothersTitle', {
- anotheruser: this.props.username
- });
- }
+ const loading = useSelector((state) => state.loading);
+ const showLoader = loading && !collection;
- getUsername() {
- return this.props.username !== undefined
- ? this.props.username
- : this.props.user.username;
- }
+ const currentUsername = useSelector((state) => state.user.username);
+ const isOwner = username === currentUsername;
- getCollectionName() {
- return this.props.collection.name;
- }
+ useEffect(() => {
+ dispatch(resetSorting());
+ }, []);
- isOwner() {
- let isOwner = false;
-
- if (
- this.props.user != null &&
- this.props.user.username &&
- this.props.collection?.owner?.username === this.props.user.username
- ) {
- isOwner = true;
+ useEffect(() => {
+ if (!collection) {
+ dispatch(getCollections(username));
}
+ }, [username, collection]);
- return isOwner;
- }
-
- hasCollection() {
- return !!this.props.collection;
- }
-
- hasCollectionItems() {
- return this.hasCollection() && this.props.collection.items.length > 0;
- }
+ const title = useMemo(() => {
+ if (collection) {
+ return `${t('Common.SiteName')} | ${collection.name}`;
+ }
+ return isOwner
+ ? t('Collection.Title')
+ : t('Collection.AnothersTitle', { anotheruser: username });
+ }, [t, username, collection, isOwner]);
- _renderLoader() {
- if (this.props.loading && !this.hasCollection()) return
- {this.props.t('Collection.NoSketches')} -
- ); - } - return null; - } + // TODO: clean this up into a generic table/list/sort component - _getButtonLabel = (fieldName, displayName) => { - const { field, direction } = this.props.sorting; + const _getButtonLabel = (fieldName, displayName) => { let buttonLabel; if (field !== fieldName) { if (field === 'name') { - buttonLabel = this.props.t('Collection.ButtonLabelAscendingARIA', { + buttonLabel = t('Collection.ButtonLabelAscendingARIA', { displayName }); } else { - buttonLabel = this.props.t('Collection.ButtonLabelDescendingARIA', { + buttonLabel = t('Collection.ButtonLabelDescendingARIA', { displayName }); } } else if (direction === SortingActions.DIRECTION.ASC) { - buttonLabel = this.props.t('Collection.ButtonLabelDescendingARIA', { + buttonLabel = t('Collection.ButtonLabelDescendingARIA', { displayName }); } else { - buttonLabel = this.props.t('Collection.ButtonLabelAscendingARIA', { + buttonLabel = t('Collection.ButtonLabelAscendingARIA', { displayName }); } return buttonLabel; }; - _renderFieldHeader(fieldName, displayName) { - const { field, direction } = this.props.sorting; + const _renderFieldHeader = (fieldName, displayName) => { const headerClass = classNames({ arrowDown: true, 'sketches-table__header--selected': field === fieldName }); - const buttonLabel = this._getButtonLabel(fieldName, displayName); return (- |
---|
+ {t('Collection.NoSketches')} +
+ )} + {hasCollectionItems && ( ++ |
---|
{t('Collection.By')} - {username} + {ownerUsername}
@@ -94,7 +87,7 @@ function CollectionMetadata({ collectionId }) {