11import PropTypes from 'prop-types' ;
22import classNames from 'classnames' ;
33import React , { useState , useRef } from 'react' ;
4- import { connect } from 'react-redux' ;
4+ import { useDispatch , useSelector } from 'react-redux' ;
55import { useTranslation } from 'react-i18next' ;
66
77import * as IDEActions from '../actions/ide' ;
88import * as FileActions from '../actions/files' ;
9+ import parseFileName from '../utils/parseFileName' ;
910import DownArrowIcon from '../../../images/down-filled-triangle.svg' ;
1011import FolderRightIcon from '../../../images/triangle-arrow-right.svg' ;
1112import FolderDownIcon from '../../../images/triangle-arrow-down.svg' ;
1213import FileTypeIcon from './FileTypeIcon' ;
1314
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-
4115function FileName ( { name } ) {
4216 const {
4317 baseName,
@@ -62,40 +36,35 @@ FileName.propTypes = {
6236 name : PropTypes . string . isRequired
6337} ;
6438
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+
8656 const [ isOptionsOpen , setIsOptionsOpen ] = useState ( false ) ;
8757 const [ isEditingName , setIsEditingName ] = useState ( false ) ;
8858 const [ isDeleting , setIsDeleting ] = useState ( false ) ;
8959 const [ updatedName , setUpdatedName ] = useState ( name ) ;
9060
91- const { t } = useTranslation ( ) ;
9261 const fileNameInput = useRef ( null ) ;
9362 const fileOptionsRef = useRef ( null ) ;
9463
9564 const handleFileClick = ( event ) => {
9665 event . stopPropagation ( ) ;
9766 if ( name !== 'root' && ! isDeleting ) {
98- setSelectedFile ( id ) ;
67+ dispatch ( IDEActions . setSelectedFile ( id ) ) ;
9968 }
10069 if ( onClickFile ) {
10170 onClickFile ( ) ;
@@ -122,17 +91,17 @@ const FileNode = ({
12291 } ;
12392
12493 const handleClickAddFile = ( ) => {
125- newFile ( id ) ;
94+ dispatch ( IDEActions . newFile ( id ) ) ;
12695 setTimeout ( ( ) => hideFileOptions ( ) , 0 ) ;
12796 } ;
12897
12998 const handleClickAddFolder = ( ) => {
130- newFolder ( id ) ;
99+ dispatch ( IDEActions . newFolder ( id ) ) ;
131100 setTimeout ( ( ) => hideFileOptions ( ) , 0 ) ;
132101 } ;
133102
134103 const handleClickUploadFile = ( ) => {
135- openUploadFileModal ( id ) ;
104+ dispatch ( IDEActions . openUploadFileModal ( id ) ) ;
136105 setTimeout ( hideFileOptions , 0 ) ;
137106 } ;
138107
@@ -141,8 +110,8 @@ const FileNode = ({
141110
142111 if ( window . confirm ( prompt ) ) {
143112 setIsDeleting ( true ) ;
144- resetSelectedFile ( id ) ;
145- setTimeout ( ( ) => deleteFile ( id , parentId ) , 100 ) ;
113+ dispatch ( IDEActions . resetSelectedFile ( id ) ) ;
114+ setTimeout ( ( ) => dispatch ( FileActions . deleteFile ( id , parentId ) , 100 ) ) ;
146115 }
147116 } ;
148117
@@ -158,7 +127,7 @@ const FileNode = ({
158127
159128 const saveUpdatedFileName = ( ) => {
160129 if ( updatedName !== name ) {
161- updateFileName ( id , updatedName ) ;
130+ dispatch ( FileActions . updateFileName ( id , updatedName ) ) ;
162131 }
163132 } ;
164133
@@ -243,7 +212,7 @@ const FileNode = ({
243212 < div className = "sidebar__file-item--folder" >
244213 < button
245214 className = "sidebar__file-item-closed"
246- onClick = { ( ) => showFolderChildren ( id ) }
215+ onClick = { ( ) => dispatch ( FileActions . showFolderChildren ( id ) ) }
247216 aria-label = { t ( 'FileNode.OpenFolderARIA' ) }
248217 title = { t ( 'FileNode.OpenFolderARIA' ) }
249218 >
@@ -255,7 +224,7 @@ const FileNode = ({
255224 </ button >
256225 < button
257226 className = "sidebar__file-item-open"
258- onClick = { ( ) => hideFolderChildren ( id ) }
227+ onClick = { ( ) => dispatch ( FileActions . hideFolderChildren ( id ) ) }
259228 aria-label = { t ( 'FileNode.CloseFolderARIA' ) }
260229 title = { t ( 'FileNode.CloseFolderARIA' ) }
261230 >
@@ -353,7 +322,7 @@ const FileNode = ({
353322 < ul className = "file-item__children" >
354323 { children . map ( ( childId ) => (
355324 < li key = { childId } >
356- < ConnectedFileNode
325+ < FileNode
357326 id = { childId }
358327 parentId = { id }
359328 canEdit = { canEdit }
@@ -369,50 +338,12 @@ const FileNode = ({
369338
370339FileNode . propTypes = {
371340 id : PropTypes . string . isRequired ,
372- parentId : PropTypes . string ,
373- children : PropTypes . arrayOf ( PropTypes . string . isRequired ) . isRequired ,
374- name : PropTypes . string . isRequired ,
375- fileType : PropTypes . string . isRequired ,
376- isSelectedFile : PropTypes . bool ,
377- isFolderClosed : PropTypes . bool ,
378- setSelectedFile : PropTypes . func . isRequired ,
379- deleteFile : PropTypes . func . isRequired ,
380- updateFileName : PropTypes . func . isRequired ,
381- resetSelectedFile : PropTypes . func . isRequired ,
382- newFile : PropTypes . func . isRequired ,
383- newFolder : PropTypes . func . isRequired ,
384- showFolderChildren : PropTypes . func . isRequired ,
385- hideFolderChildren : PropTypes . func . isRequired ,
386341 canEdit : PropTypes . bool . isRequired ,
387- openUploadFileModal : PropTypes . func . isRequired ,
388- authenticated : PropTypes . bool . isRequired ,
389342 onClickFile : PropTypes . func
390343} ;
391344
392345FileNode . defaultProps = {
393- onClickFile : null ,
394- parentId : '0' ,
395- isSelectedFile : false ,
396- isFolderClosed : false
346+ onClickFile : null
397347} ;
398348
399- function mapStateToProps ( state , ownProps ) {
400- // this is a hack, state is updated before ownProps
401- const fileNode = state . files . find ( ( file ) => file . id === ownProps . id ) || {
402- name : 'test' ,
403- fileType : 'file'
404- } ;
405- return Object . assign ( { } , fileNode , {
406- authenticated : state . user . authenticated
407- } ) ;
408- }
409-
410- const mapDispatchToProps = { ...FileActions , ...IDEActions } ;
411-
412- const ConnectedFileNode = connect (
413- mapStateToProps ,
414- mapDispatchToProps
415- ) ( FileNode ) ;
416-
417- export { FileNode } ;
418- export default ConnectedFileNode ;
349+ export default FileNode ;
0 commit comments