1
1
import PropTypes from 'prop-types' ;
2
2
import classNames from 'classnames' ;
3
3
import React , { useState , useRef } from 'react' ;
4
- import { connect , useDispatch } from 'react-redux' ;
4
+ import { useDispatch , useSelector } from 'react-redux' ;
5
5
import { useTranslation } from 'react-i18next' ;
6
6
7
7
import * as IDEActions from '../actions/ide' ;
8
8
import * as FileActions from '../actions/files' ;
9
+ import parseFileName from '../utils/parseFileName' ;
9
10
import DownArrowIcon from '../../../images/down-filled-triangle.svg' ;
10
11
import FolderRightIcon from '../../../images/triangle-arrow-right.svg' ;
11
12
import FolderDownIcon from '../../../images/triangle-arrow-down.svg' ;
12
13
import FileTypeIcon from './FileTypeIcon' ;
13
14
14
- function parseFileName ( name ) {
15
- const nameArray = name . split ( '.' ) ;
16
- if ( nameArray . length > 1 ) {
17
- const extension = `.${ nameArray [ nameArray . length - 1 ] } ` ;
18
- const baseName = nameArray . slice ( 0 , - 1 ) . join ( '.' ) ;
19
- const firstLetter = baseName [ 0 ] ;
20
- const lastLetter = baseName [ baseName . length - 1 ] ;
21
- const middleText = baseName . slice ( 1 , - 1 ) ;
22
- return {
23
- baseName,
24
- firstLetter,
25
- lastLetter,
26
- middleText,
27
- extension
28
- } ;
29
- }
30
- const firstLetter = name [ 0 ] ;
31
- const lastLetter = name [ name . length - 1 ] ;
32
- const middleText = name . slice ( 1 , - 1 ) ;
33
- return {
34
- baseName : name ,
35
- firstLetter,
36
- lastLetter,
37
- middleText
38
- } ;
39
- }
40
-
41
15
function FileName ( { name } ) {
42
16
const {
43
17
baseName,
@@ -62,41 +36,35 @@ FileName.propTypes = {
62
36
name : PropTypes . string . isRequired
63
37
} ;
64
38
65
- const FileNode = ( {
66
- id,
67
- parentId,
68
- children,
69
- name,
70
- fileType,
71
- isSelectedFile,
72
- isFolderClosed,
73
- setSelectedFile,
74
- deleteFile,
75
- updateFileName,
76
- resetSelectedFile,
77
- newFile,
78
- newFolder,
79
- showFolderChildren,
80
- hideFolderChildren,
81
- canEdit,
82
- openUploadFileModal,
83
- authenticated,
84
- onClickFile
85
- } ) => {
39
+ const FileNode = ( { id, canEdit, onClickFile } ) => {
40
+ const dispatch = useDispatch ( ) ;
41
+ const { t } = useTranslation ( ) ;
42
+
43
+ const fileNode =
44
+ useSelector ( ( state ) => state . files . find ( ( file ) => file . id === id ) ) || { } ;
45
+ const authenticated = useSelector ( ( state ) => state . user . authenticated ) ;
46
+
47
+ const {
48
+ name = '' ,
49
+ parentId = null ,
50
+ children = [ ] ,
51
+ fileType = 'file' ,
52
+ isSelectedFile = false ,
53
+ isFolderClosed = false
54
+ } = fileNode ;
55
+
86
56
const [ isOptionsOpen , setIsOptionsOpen ] = useState ( false ) ;
87
57
const [ isEditingName , setIsEditingName ] = useState ( false ) ;
88
58
const [ isDeleting , setIsDeleting ] = useState ( false ) ;
89
59
const [ updatedName , setUpdatedName ] = useState ( name ) ;
90
- const dispatch = useDispatch ( ) ;
91
60
92
- const { t } = useTranslation ( ) ;
93
61
const fileNameInput = useRef ( null ) ;
94
62
const fileOptionsRef = useRef ( null ) ;
95
63
96
64
const handleFileClick = ( event ) => {
97
65
event . stopPropagation ( ) ;
98
66
if ( name !== 'root' && ! isDeleting ) {
99
- setSelectedFile ( id ) ;
67
+ dispatch ( IDEActions . setSelectedFile ( id ) ) ;
100
68
}
101
69
if ( onClickFile ) {
102
70
onClickFile ( ) ;
@@ -123,17 +91,17 @@ const FileNode = ({
123
91
} ;
124
92
125
93
const handleClickAddFile = ( ) => {
126
- dispatch ( newFile ( id ) ) ;
94
+ dispatch ( IDEActions . newFile ( id ) ) ;
127
95
setTimeout ( ( ) => hideFileOptions ( ) , 0 ) ;
128
96
} ;
129
97
130
98
const handleClickAddFolder = ( ) => {
131
- dispatch ( newFolder ( id ) ) ;
99
+ dispatch ( IDEActions . newFolder ( id ) ) ;
132
100
setTimeout ( ( ) => hideFileOptions ( ) , 0 ) ;
133
101
} ;
134
102
135
103
const handleClickUploadFile = ( ) => {
136
- dispatch ( openUploadFileModal ( id ) ) ;
104
+ dispatch ( IDEActions . openUploadFileModal ( id ) ) ;
137
105
setTimeout ( hideFileOptions , 0 ) ;
138
106
} ;
139
107
@@ -142,8 +110,8 @@ const FileNode = ({
142
110
143
111
if ( window . confirm ( prompt ) ) {
144
112
setIsDeleting ( true ) ;
145
- resetSelectedFile ( id ) ;
146
- setTimeout ( ( ) => deleteFile ( id , parentId ) , 100 ) ;
113
+ dispatch ( IDEActions . resetSelectedFile ( id ) ) ;
114
+ setTimeout ( ( ) => dispatch ( FileActions . deleteFile ( id , parentId ) , 100 ) ) ;
147
115
}
148
116
} ;
149
117
@@ -159,7 +127,7 @@ const FileNode = ({
159
127
160
128
const saveUpdatedFileName = ( ) => {
161
129
if ( updatedName !== name ) {
162
- updateFileName ( id , updatedName ) ;
130
+ dispatch ( FileActions . updateFileName ( id , updatedName ) ) ;
163
131
}
164
132
} ;
165
133
@@ -244,7 +212,7 @@ const FileNode = ({
244
212
< div className = "sidebar__file-item--folder" >
245
213
< button
246
214
className = "sidebar__file-item-closed"
247
- onClick = { ( ) => showFolderChildren ( id ) }
215
+ onClick = { ( ) => dispatch ( FileActions . showFolderChildren ( id ) ) }
248
216
aria-label = { t ( 'FileNode.OpenFolderARIA' ) }
249
217
title = { t ( 'FileNode.OpenFolderARIA' ) }
250
218
>
@@ -256,7 +224,7 @@ const FileNode = ({
256
224
</ button >
257
225
< button
258
226
className = "sidebar__file-item-open"
259
- onClick = { ( ) => hideFolderChildren ( id ) }
227
+ onClick = { ( ) => dispatch ( FileActions . hideFolderChildren ( id ) ) }
260
228
aria-label = { t ( 'FileNode.CloseFolderARIA' ) }
261
229
title = { t ( 'FileNode.CloseFolderARIA' ) }
262
230
>
@@ -354,7 +322,7 @@ const FileNode = ({
354
322
< ul className = "file-item__children" >
355
323
{ children . map ( ( childId ) => (
356
324
< li key = { childId } >
357
- < ConnectedFileNode
325
+ < FileNode
358
326
id = { childId }
359
327
parentId = { id }
360
328
canEdit = { canEdit }
@@ -370,50 +338,12 @@ const FileNode = ({
370
338
371
339
FileNode . propTypes = {
372
340
id : PropTypes . string . isRequired ,
373
- parentId : PropTypes . string ,
374
- children : PropTypes . arrayOf ( PropTypes . string . isRequired ) . isRequired ,
375
- name : PropTypes . string . isRequired ,
376
- fileType : PropTypes . string . isRequired ,
377
- isSelectedFile : PropTypes . bool ,
378
- isFolderClosed : PropTypes . bool ,
379
- setSelectedFile : PropTypes . func . isRequired ,
380
- deleteFile : PropTypes . func . isRequired ,
381
- updateFileName : PropTypes . func . isRequired ,
382
- resetSelectedFile : PropTypes . func . isRequired ,
383
- newFile : PropTypes . func . isRequired ,
384
- newFolder : PropTypes . func . isRequired ,
385
- showFolderChildren : PropTypes . func . isRequired ,
386
- hideFolderChildren : PropTypes . func . isRequired ,
387
341
canEdit : PropTypes . bool . isRequired ,
388
- openUploadFileModal : PropTypes . func . isRequired ,
389
- authenticated : PropTypes . bool . isRequired ,
390
342
onClickFile : PropTypes . func
391
343
} ;
392
344
393
345
FileNode . defaultProps = {
394
- onClickFile : null ,
395
- parentId : '0' ,
396
- isSelectedFile : false ,
397
- isFolderClosed : false
346
+ onClickFile : null
398
347
} ;
399
348
400
- function mapStateToProps ( state , ownProps ) {
401
- // this is a hack, state is updated before ownProps
402
- const fileNode = state . files . find ( ( file ) => file . id === ownProps . id ) || {
403
- name : 'test' ,
404
- fileType : 'file'
405
- } ;
406
- return Object . assign ( { } , fileNode , {
407
- authenticated : state . user . authenticated
408
- } ) ;
409
- }
410
-
411
- const mapDispatchToProps = { ...FileActions , ...IDEActions } ;
412
-
413
- const ConnectedFileNode = connect (
414
- mapStateToProps ,
415
- mapDispatchToProps
416
- ) ( FileNode ) ;
417
-
418
- export { FileNode } ;
419
- export default ConnectedFileNode ;
349
+ export default FileNode ;
0 commit comments