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' ;
7- // import { find } from 'lodash';
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' ;
128import getSortedSketches from '../selectors/projects' ;
139import Loader from '../../App/components/loader' ;
1410import QuickAddList from './QuickAddList' ;
@@ -17,149 +13,79 @@ import {
1713 QuickAddWrapper
1814} from './AddToCollectionList' ;
1915
20- class SketchList extends React . Component {
21- constructor ( props ) {
22- super ( props ) ;
23- this . props . getProjects ( this . props . username ) ;
16+ const AddToCollectionSketchList = ( { collection } ) => {
17+ const { t } = useTranslation ( ) ;
2418
25- this . state = {
26- isInitialDataLoad : true
27- } ;
28- }
19+ const dispatch = useDispatch ( ) ;
2920
30- componentWillReceiveProps ( nextProps ) {
31- if (
32- this . props . sketches !== nextProps . sketches &&
33- Array . isArray ( nextProps . sketches )
34- ) {
35- this . setState ( {
36- isInitialDataLoad : false
37- } ) ;
38- }
39- }
21+ const username = useSelector ( ( state ) => state . user . username ) ;
4022
41- getSketchesTitle ( ) {
42- if ( this . props . username === this . props . user . username ) {
43- return this . props . t ( 'AddToCollectionSketchList.Title' ) ;
44- }
45- return this . props . t ( 'AddToCollectionSketchList.AnothersTitle' , {
46- anotheruser : this . props . username
47- } ) ;
48- }
23+ const sketches = useSelector ( getSortedSketches ) ;
4924
50- handleCollectionAdd = ( sketch ) => {
51- this . props . addToCollection ( this . props . collection . id , sketch . id ) ;
52- } ;
53-
54- handleCollectionRemove = ( sketch ) => {
55- this . props . removeFromCollection ( this . props . collection . id , sketch . id ) ;
56- } ;
25+ // TODO: improve loading state
26+ const loading = useSelector ( ( state ) => state . loading ) ;
27+ const [ hasLoadedData , setHasLoadedData ] = useState ( false ) ;
28+ const showLoader = loading && ! hasLoadedData ;
5729
58- inCollection = ( sketch ) =>
59- this . props . collection . items . find ( ( item ) =>
60- item . isDeleted ? false : item . project . id === sketch . id
61- ) != null ;
30+ useEffect ( ( ) => {
31+ dispatch ( getProjects ( username ) ) . then ( ( ) => setHasLoadedData ( true ) ) ;
32+ } , [ dispatch , username ] ) ;
6233
63- render ( ) {
64- const hasSketches = this . props . sketches . length > 0 ;
65- const sketchesWithAddedStatus = this . props . sketches . map ( ( sketch ) => ( {
66- ...sketch ,
67- isAdded : this . inCollection ( sketch ) ,
68- url : `/${ this . props . username } /sketches/${ sketch . id } `
69- } ) ) ;
34+ const handleCollectionAdd = ( sketch ) => {
35+ dispatch ( addToCollection ( collection . id , sketch . id ) ) ;
36+ } ;
7037
71- let content = null ;
38+ const handleCollectionRemove = ( sketch ) => {
39+ dispatch ( removeFromCollection ( collection . id , sketch . id ) ) ;
40+ } ;
7241
73- if ( this . props . loading && this . state . isInitialDataLoad ) {
74- content = < Loader /> ;
75- } else if ( hasSketches ) {
76- content = (
77- < QuickAddList
78- items = { sketchesWithAddedStatus }
79- onAdd = { this . handleCollectionAdd }
80- onRemove = { this . handleCollectionRemove }
81- />
82- ) ;
83- } else {
84- content = this . props . t ( 'AddToCollectionSketchList.NoCollections' ) ;
42+ const sketchesWithAddedStatus = sketches . map ( ( sketch ) => ( {
43+ ...sketch ,
44+ url : `/${ username } /sketches/${ sketch . id } ` ,
45+ isAdded : collection . items . some (
46+ ( item ) => item . projectId === sketch . id && ! item . isDeleted
47+ )
48+ } ) ) ;
49+
50+ const getContent = ( ) => {
51+ if ( showLoader ) {
52+ return < Loader /> ;
53+ } else if ( sketches . length === 0 ) {
54+ // TODO: shouldn't it be NoSketches? -Linda
55+ return t ( 'AddToCollectionSketchList.NoCollections' ) ;
8556 }
86-
8757 return (
88- < CollectionAddSketchWrapper >
89- < QuickAddWrapper >
90- < Helmet >
91- < title > { this . getSketchesTitle ( ) } </ title >
92- </ Helmet >
93- { content }
94- </ QuickAddWrapper >
95- </ CollectionAddSketchWrapper >
58+ < QuickAddList
59+ items = { sketchesWithAddedStatus }
60+ onAdd = { handleCollectionAdd }
61+ onRemove = { handleCollectionRemove }
62+ />
9663 ) ;
97- }
98- }
64+ } ;
9965
100- SketchList . propTypes = {
101- user : PropTypes . shape ( {
102- username : PropTypes . string ,
103- authenticated : PropTypes . bool . isRequired
104- } ) . isRequired ,
105- getProjects : PropTypes . func . isRequired ,
106- sketches : PropTypes . arrayOf (
107- PropTypes . shape ( {
108- id : PropTypes . string . isRequired ,
109- name : PropTypes . string . isRequired ,
110- createdAt : PropTypes . string . isRequired ,
111- updatedAt : PropTypes . string . isRequired
112- } )
113- ) . isRequired ,
66+ return (
67+ < CollectionAddSketchWrapper >
68+ < QuickAddWrapper >
69+ < Helmet >
70+ < title > { t ( 'AddToCollectionSketchList.Title' ) } </ title >
71+ </ Helmet >
72+ { getContent ( ) }
73+ </ QuickAddWrapper >
74+ </ CollectionAddSketchWrapper >
75+ ) ;
76+ } ;
77+
78+ AddToCollectionSketchList . propTypes = {
11479 collection : PropTypes . shape ( {
11580 id : PropTypes . string . isRequired ,
11681 name : PropTypes . string . isRequired ,
11782 items : PropTypes . arrayOf (
11883 PropTypes . shape ( {
119- project : PropTypes . shape ( {
120- id : PropTypes . string . isRequired
121- } )
84+ projectId : PropTypes . string . isRequired ,
85+ isDeleted : PropTypes . bool
12286 } )
12387 )
124- } ) . isRequired ,
125- username : PropTypes . string ,
126- loading : PropTypes . bool . isRequired ,
127- sorting : PropTypes . shape ( {
128- field : PropTypes . string . isRequired ,
129- direction : PropTypes . string . isRequired
130- } ) . isRequired ,
131- addToCollection : PropTypes . func . isRequired ,
132- removeFromCollection : PropTypes . func . isRequired ,
133- t : PropTypes . func . isRequired
134- } ;
135-
136- SketchList . defaultProps = {
137- username : undefined
88+ } ) . isRequired
13889} ;
13990
140- function mapStateToProps ( state ) {
141- return {
142- user : state . user ,
143- sketches : getSortedSketches ( state ) ,
144- sorting : state . sorting ,
145- loading : state . loading ,
146- project : state . project
147- } ;
148- }
149-
150- function mapDispatchToProps ( dispatch ) {
151- return bindActionCreators (
152- Object . assign (
153- { } ,
154- ProjectsActions ,
155- CollectionsActions ,
156- ToastActions ,
157- SortingActions
158- ) ,
159- dispatch
160- ) ;
161- }
162-
163- export default withTranslation ( ) (
164- connect ( mapStateToProps , mapDispatchToProps ) ( SketchList )
165- ) ;
91+ export default AddToCollectionSketchList ;
0 commit comments