@@ -5,137 +5,91 @@ import TreeView from "@material-ui/lab/TreeView"
5
5
import TreeItem from "@material-ui/lab/TreeItem"
6
6
import Menu from "@material-ui/core/Menu"
7
7
import MenuItem from "@material-ui/core/MenuItem"
8
- import { FC , useMemo , useState } from "react"
8
+ import { FC , useState } from "react"
9
9
import { TemplateVersionFileTree } from "util/templateVersion"
10
10
import { DockerIcon } from "components/Icons/DockerIcon"
11
11
12
- export interface File {
13
- path : string
14
- content ?: string
15
- children : Record < string , File >
16
- }
17
-
18
- const mapFileTreeToFiles = (
19
- fileTree : TemplateVersionFileTree ,
20
- parent ?: string ,
21
- ) : Record < string , File > => {
22
- const files : Record < string , File > = { }
23
-
24
- Object . keys ( fileTree ) . forEach ( ( filename ) => {
25
- const currentPath = parent ? `${ parent } /${ filename } ` : filename
26
- const content = fileTree [ filename ]
27
- if ( typeof content === "string" ) {
28
- files [ currentPath ] = {
29
- path : currentPath ,
30
- content,
31
- children : { } ,
32
- }
33
- } else {
34
- files [ currentPath ] = {
35
- path : currentPath ,
36
- children : mapFileTreeToFiles ( content , currentPath ) ,
37
- }
38
- }
39
- } )
40
-
41
- return files
42
- }
43
-
44
- const sortFileChildren = ( file : File ) => ( a : string , b : string ) => {
45
- const child = file . children [ a ]
46
- const childB = file . children [ b ]
47
- if ( child . content === undefined ) {
48
- return - 1
49
- }
50
- if ( childB . content === undefined ) {
51
- return 1
52
- }
53
- return a . localeCompare ( b )
54
- }
55
-
56
- const sortRootFiles =
57
- ( rootFiles : Record < string , File > ) => ( a : string , b : string ) => {
58
- const child = rootFiles [ a ]
59
- const childB = rootFiles [ b ]
60
- if ( child . content === undefined ) {
12
+ const sortFileTree =
13
+ ( fileTree : TemplateVersionFileTree ) => ( a : string , b : string ) => {
14
+ const contentA = fileTree [ a ]
15
+ const contentB = fileTree [ b ]
16
+ if ( typeof contentA === "object" ) {
61
17
return - 1
62
18
}
63
- if ( childB . content === undefined ) {
19
+ if ( typeof contentB === "object" ) {
64
20
return 1
65
21
}
66
22
return a . localeCompare ( b )
67
23
}
68
24
25
+ type ContextMenu = {
26
+ path : string
27
+ clientX : number
28
+ clientY : number
29
+ }
30
+
69
31
export const FileTree : FC < {
70
- onSelect : ( file : File ) => void
71
- onDelete : ( file : File ) => void
72
- onRename : ( file : File ) => void
73
- files : TemplateVersionFileTree
74
- activeFile ?: File
75
- } > = ( { activeFile , files , onDelete, onRename, onSelect } ) => {
32
+ onSelect : ( path : string ) => void
33
+ onDelete : ( path : string ) => void
34
+ onRename : ( path : string ) => void
35
+ fileTree : TemplateVersionFileTree
36
+ activePath ?: string
37
+ } > = ( { fileTree , activePath , onDelete, onRename, onSelect } ) => {
76
38
const styles = useStyles ( )
77
- const fileTree = useMemo < Record < string , File > > (
78
- ( ) => mapFileTreeToFiles ( files ) ,
79
- [ files ] ,
80
- )
81
- const [ contextMenu , setContextMenu ] = useState <
82
- | {
83
- file : File
84
- clientX : number
85
- clientY : number
86
- }
87
- | undefined
88
- > ( )
89
-
90
- const buildTreeItems = ( name : string , file : File ) : JSX . Element => {
39
+ const [ contextMenu , setContextMenu ] = useState < ContextMenu | undefined > ( )
40
+
41
+ const buildTreeItems = (
42
+ filename : string ,
43
+ content ?: TemplateVersionFileTree | string ,
44
+ parentPath ?: string ,
45
+ ) : JSX . Element => {
46
+ const currentPath = parentPath ? `${ parentPath } /${ filename } ` : filename
91
47
let icon : JSX . Element | null = null
92
- if ( file . path . endsWith ( ".tf" ) ) {
48
+ if ( filename . endsWith ( ".tf" ) ) {
93
49
icon = < FileTypeTerraform />
94
50
}
95
- if ( file . path . endsWith ( ".md" ) ) {
51
+ if ( filename . endsWith ( ".md" ) ) {
96
52
icon = < FileTypeMarkdown />
97
53
}
98
- if ( file . path . endsWith ( "Dockerfile" ) ) {
54
+ if ( filename . endsWith ( "Dockerfile" ) ) {
99
55
icon = < FileTypeDockerfile />
100
56
}
101
57
102
58
return (
103
59
< TreeItem
104
- nodeId = { file . path }
105
- key = { file . path }
106
- label = { name }
60
+ nodeId = { currentPath }
61
+ key = { currentPath }
62
+ label = { filename }
107
63
className = { `${ styles . fileTreeItem } ${
108
- file . path === activeFile ?. path ? "active" : ""
64
+ currentPath === activePath ? "active" : ""
109
65
} `}
110
66
onClick = { ( ) => {
111
- // Content can be an empty string
112
- if ( file . content !== undefined ) {
113
- onSelect ( file )
114
- }
67
+ onSelect ( currentPath )
115
68
} }
116
69
onContextMenu = { ( event ) => {
117
70
event . preventDefault ( )
118
- if ( ! file . content ) {
119
- return
120
- }
121
71
setContextMenu (
122
72
contextMenu
123
73
? undefined
124
74
: {
125
- file : file ,
75
+ path : currentPath ,
126
76
clientY : event . clientY ,
127
77
clientX : event . clientX ,
128
78
} ,
129
79
)
130
80
} }
131
81
icon = { icon }
132
82
>
133
- { Object . keys ( file . children )
134
- . sort ( sortFileChildren ( file ) )
135
- . map ( ( path ) => {
136
- const child = file . children [ path ]
137
- return buildTreeItems ( path , child )
138
- } ) }
83
+ { typeof content === "object" ? (
84
+ Object . keys ( content )
85
+ . sort ( sortFileTree ( content ) )
86
+ . map ( ( filename ) => {
87
+ const child = content [ filename ]
88
+ return buildTreeItems ( filename , child , currentPath )
89
+ } )
90
+ ) : (
91
+ < > </ >
92
+ ) }
139
93
</ TreeItem >
140
94
)
141
95
}
@@ -148,10 +102,10 @@ export const FileTree: FC<{
148
102
className = { styles . fileTree }
149
103
>
150
104
{ Object . keys ( fileTree )
151
- . sort ( sortRootFiles ( fileTree ) )
152
- . map ( ( path ) => {
153
- const child = fileTree [ path ]
154
- return buildTreeItems ( path , child )
105
+ . sort ( sortFileTree ( fileTree ) )
106
+ . map ( ( filename ) => {
107
+ const child = fileTree [ filename ]
108
+ return buildTreeItems ( filename , child )
155
109
} ) }
156
110
157
111
< Menu
@@ -180,7 +134,7 @@ export const FileTree: FC<{
180
134
if ( ! contextMenu ) {
181
135
return
182
136
}
183
- onRename ( contextMenu . file )
137
+ onRename ( contextMenu . path )
184
138
setContextMenu ( undefined )
185
139
} }
186
140
>
@@ -191,7 +145,7 @@ export const FileTree: FC<{
191
145
if ( ! contextMenu ) {
192
146
return
193
147
}
194
- onDelete ( contextMenu . file )
148
+ onDelete ( contextMenu . path )
195
149
setContextMenu ( undefined )
196
150
} }
197
151
>
0 commit comments