11import PropTypes from 'prop-types' ;
2- import React from 'react' ;
2+ import React , { useEffect , useState } from 'react' ;
33import { Helmet } from 'react-helmet' ;
4- import { connect } from 'react-redux' ;
5- import { bindActionCreators } from 'redux' ;
6- import { withTranslation } from 'react-i18next' ;
4+ import { useTranslation } from 'react-i18next' ;
5+ import { useDispatch , useSelector } from 'react-redux' ;
76import styled from 'styled-components' ;
8- import * as ProjectActions from '../actions/project' ;
9- import * as ProjectsActions from '../actions/projects' ;
10- import * as CollectionsActions from '../actions/collections' ;
11- import * as ToastActions from '../actions/toast' ;
12- import * as SortingActions from '../actions/sorting' ;
13- import getSortedCollections from '../selectors/collections' ;
147import Loader from '../../App/components/loader' ;
8+ import {
9+ addToCollection ,
10+ getCollections ,
11+ removeFromCollection
12+ } from '../actions/collections' ;
13+ import getSortedCollections from '../selectors/collections' ;
1514import QuickAddList from './QuickAddList' ;
1615import { remSize } from '../../../theme' ;
1716
18- const projectInCollection = ( project , collection ) =>
19- collection . items . find ( ( item ) => item . projectId === project . id ) != null ;
20-
2117export const CollectionAddSketchWrapper = styled . div `
2218 width: ${ remSize ( 600 ) } ;
2319 max-width: 100%;
@@ -31,166 +27,67 @@ export const QuickAddWrapper = styled.div`
3127 height: 100%;
3228` ;
3329
34- class CollectionList extends React . Component {
35- constructor ( props ) {
36- super ( props ) ;
30+ const AddToCollectionList = ( { projectId } ) => {
31+ const { t } = useTranslation ( ) ;
3732
38- if ( props . projectId ) {
39- props . getProject ( props . projectId ) ;
40- }
33+ const dispatch = useDispatch ( ) ;
4134
42- this . props . getCollections ( this . props . user . username ) ;
35+ const username = useSelector ( ( state ) => state . user . username ) ;
4336
44- this . state = {
45- hasLoadedData : false
46- } ;
47- }
37+ const collections = useSelector ( getSortedCollections ) ;
4838
49- componentDidUpdate ( prevProps ) {
50- if ( prevProps . loading === true && this . props . loading === false ) {
51- // eslint-disable-next-line react/no-did-update-set-state
52- this . setState ( {
53- hasLoadedData : true
54- } ) ;
55- }
56- }
39+ // TODO: improve loading state
40+ const loading = useSelector ( ( state ) => state . loading ) ;
41+ const [ hasLoadedData , setHasLoadedData ] = useState ( false ) ;
42+ const showLoader = loading && ! hasLoadedData ;
5743
58- getTitle ( ) {
59- if ( this . props . username === this . props . user . username ) {
60- return this . props . t ( 'AddToCollectionList.Title' ) ;
61- }
62- return this . props . t ( 'AddToCollectionList.AnothersTitle' , {
63- anotheruser : this . props . username
64- } ) ;
65- }
44+ useEffect ( ( ) => {
45+ dispatch ( getCollections ( username ) ) . then ( ( ) => setHasLoadedData ( true ) ) ;
46+ } , [ dispatch , username ] ) ;
6647
67- handleCollectionAdd = ( collection ) => {
68- this . props . addToCollection ( collection . id , this . props . project . id ) ;
48+ const handleCollectionAdd = ( collection ) => {
49+ dispatch ( addToCollection ( collection . id , projectId ) ) ;
6950 } ;
7051
71- handleCollectionRemove = ( collection ) => {
72- this . props . removeFromCollection ( collection . id , this . props . project . id ) ;
52+ const handleCollectionRemove = ( collection ) => {
53+ dispatch ( removeFromCollection ( collection . id , projectId ) ) ;
7354 } ;
7455
75- render ( ) {
76- const { collections, project } = this . props ;
77- const hasCollections = collections . length > 0 ;
78- const collectionWithSketchStatus = collections . map ( ( collection ) => ( {
79- ...collection ,
80- url : `/${ collection . owner . username } /collections/${ collection . id } ` ,
81- isAdded : projectInCollection ( project , collection )
82- } ) ) ;
83-
84- let content = null ;
85-
86- if ( this . props . loading && ! this . state . hasLoadedData ) {
87- content = < Loader /> ;
88- } else if ( hasCollections ) {
89- content = (
90- < QuickAddList
91- items = { collectionWithSketchStatus }
92- onAdd = { this . handleCollectionAdd }
93- onRemove = { this . handleCollectionRemove }
94- t = { this . props . t }
95- />
96- ) ;
97- } else {
98- content = this . props . t ( 'AddToCollectionList.Empty' ) ;
56+ const collectionWithSketchStatus = collections . map ( ( collection ) => ( {
57+ ...collection ,
58+ url : `/${ collection . owner . username } /collections/${ collection . id } ` ,
59+ isAdded : collection . items . some ( ( item ) => item . projectId === projectId )
60+ } ) ) ;
61+
62+ const getContent = ( ) => {
63+ if ( showLoader ) {
64+ return < Loader /> ;
65+ } else if ( collections . length === 0 ) {
66+ return t ( 'AddToCollectionList.Empty' ) ;
9967 }
100-
10168 return (
102- < CollectionAddSketchWrapper >
103- < QuickAddWrapper >
104- < Helmet >
105- < title > { this . getTitle ( ) } </ title >
106- </ Helmet >
107- { content }
108- </ QuickAddWrapper >
109- </ CollectionAddSketchWrapper >
69+ < QuickAddList
70+ items = { collectionWithSketchStatus }
71+ onAdd = { handleCollectionAdd }
72+ onRemove = { handleCollectionRemove }
73+ />
11074 ) ;
111- }
112- }
113-
114- const ProjectShape = PropTypes . shape ( {
115- id : PropTypes . string . isRequired ,
116- name : PropTypes . string . isRequired ,
117- createdAt : PropTypes . string . isRequired ,
118- updatedAt : PropTypes . string . isRequired ,
119- user : PropTypes . shape ( {
120- username : PropTypes . string . isRequired
121- } ) . isRequired
122- } ) ;
123-
124- const ItemsShape = PropTypes . shape ( {
125- createdAt : PropTypes . string . isRequired ,
126- updatedAt : PropTypes . string . isRequired ,
127- project : ProjectShape
128- } ) ;
75+ } ;
12976
130- CollectionList . propTypes = {
131- user : PropTypes . shape ( {
132- username : PropTypes . string ,
133- authenticated : PropTypes . bool . isRequired
134- } ) . isRequired ,
135- projectId : PropTypes . string . isRequired ,
136- getCollections : PropTypes . func . isRequired ,
137- getProject : PropTypes . func . isRequired ,
138- addToCollection : PropTypes . func . isRequired ,
139- removeFromCollection : PropTypes . func . isRequired ,
140- collections : PropTypes . arrayOf (
141- PropTypes . shape ( {
142- id : PropTypes . string . isRequired ,
143- name : PropTypes . string . isRequired ,
144- description : PropTypes . string ,
145- createdAt : PropTypes . string . isRequired ,
146- updatedAt : PropTypes . string . isRequired ,
147- items : PropTypes . arrayOf ( ItemsShape )
148- } )
149- ) . isRequired ,
150- username : PropTypes . string ,
151- loading : PropTypes . bool . isRequired ,
152- project : PropTypes . shape ( {
153- id : PropTypes . string ,
154- owner : PropTypes . shape ( {
155- id : PropTypes . string
156- } )
157- } ) ,
158- t : PropTypes . func . isRequired
77+ return (
78+ < CollectionAddSketchWrapper >
79+ < QuickAddWrapper >
80+ < Helmet >
81+ < title > { t ( 'AddToCollectionList.Title' ) } </ title >
82+ </ Helmet >
83+ { getContent ( ) }
84+ </ QuickAddWrapper >
85+ </ CollectionAddSketchWrapper >
86+ ) ;
15987} ;
16088
161- CollectionList . defaultProps = {
162- project : {
163- id : undefined ,
164- owner : undefined
165- } ,
166- username : undefined
89+ AddToCollectionList . propTypes = {
90+ projectId : PropTypes . string . isRequired
16791} ;
16892
169- function mapStateToProps ( state , ownProps ) {
170- return {
171- user : state . user ,
172- collections : getSortedCollections ( state ) ,
173- sorting : state . sorting ,
174- loading : state . loading ,
175- project : ownProps . project || state . project ,
176- projectId : ownProps && ownProps . params ? ownProps . prams . project_id : null
177- } ;
178- }
179-
180- function mapDispatchToProps ( dispatch ) {
181- return bindActionCreators (
182- Object . assign (
183- { } ,
184- CollectionsActions ,
185- ProjectsActions ,
186- ProjectActions ,
187- ToastActions ,
188- SortingActions
189- ) ,
190- dispatch
191- ) ;
192- }
193-
194- export default withTranslation ( ) (
195- connect ( mapStateToProps , mapDispatchToProps ) ( CollectionList )
196- ) ;
93+ export default AddToCollectionList ;
0 commit comments