Skip to content

Commit a3201bd

Browse files
fix(site): Fix template version editor rename (#6251)
1 parent 1483b42 commit a3201bd

File tree

10 files changed

+205
-56
lines changed

10 files changed

+205
-56
lines changed

site/src/components/Dialogs/ConfirmDialog/ConfirmDialog.tsx

+5-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,11 @@ const useStyles = makeStyles((theme) => ({
8787
color: theme.palette.text.primary,
8888
},
8989

90-
"& p": {
90+
"& p:not(.MuiFormHelperText-root)": {
91+
margin: 0,
92+
},
93+
94+
"& > p": {
9195
margin: theme.spacing(1, 0),
9296
},
9397
},

site/src/components/TemplateVersionEditor/FileDialog.tsx

+57-16
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,18 @@ import { ConfirmDialog } from "components/Dialogs/ConfirmDialog/ConfirmDialog"
33
import { Stack } from "components/Stack/Stack"
44
import { ChangeEvent, FC, useState } from "react"
55
import Typography from "@material-ui/core/Typography"
6+
import { allowedExtensions, isAllowedFile } from "util/templateVersion"
7+
import { FileTree, validatePath } from "util/filetree"
68

79
export const CreateFileDialog: FC<{
810
onClose: () => void
911
checkExists: (path: string) => boolean
1012
onConfirm: (path: string) => void
1113
open: boolean
12-
}> = ({ checkExists, onClose, onConfirm, open }) => {
14+
fileTree: FileTree
15+
}> = ({ checkExists, onClose, onConfirm, open, fileTree }) => {
1316
const [pathValue, setPathValue] = useState("")
14-
const [error, setError] = useState("")
17+
const [error, setError] = useState<string>()
1518
const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
1619
setPathValue(event.target.value)
1720
}
@@ -24,7 +27,20 @@ export const CreateFileDialog: FC<{
2427
setError("File already exists")
2528
return
2629
}
30+
if (!isAllowedFile(pathValue)) {
31+
const extensions = allowedExtensions.join(", ")
32+
setError(
33+
`This extension is not allowed. You only can create files with the following extensions: ${extensions}.`,
34+
)
35+
return
36+
}
37+
const pathError = validatePath(pathValue, fileTree)
38+
if (pathError) {
39+
setError(pathError)
40+
return
41+
}
2742
onConfirm(pathValue)
43+
setError(undefined)
2844
setPathValue("")
2945
}
3046

@@ -33,6 +49,7 @@ export const CreateFileDialog: FC<{
3349
open={open}
3450
onClose={() => {
3551
onClose()
52+
setError(undefined)
3653
setPathValue("")
3754
}}
3855
onConfirm={handleConfirm}
@@ -42,10 +59,10 @@ export const CreateFileDialog: FC<{
4259
confirmText="Create"
4360
title="Create File"
4461
description={
45-
<Stack spacing={1}>
62+
<Stack>
4663
<Typography>
4764
Specify the path to a file to be created. This path can contain
48-
slashes too!
65+
slashes too.
4966
</Typography>
5067
<TextField
5168
autoFocus
@@ -54,14 +71,18 @@ export const CreateFileDialog: FC<{
5471
handleConfirm()
5572
}
5673
}}
74+
error={Boolean(error)}
5775
helperText={error}
5876
name="file-path"
5977
autoComplete="off"
6078
id="file-path"
61-
placeholder="main.tf"
79+
placeholder="example.tf"
6280
value={pathValue}
6381
onChange={handleChange}
6482
label="File Path"
83+
InputLabelProps={{
84+
shrink: true,
85+
}}
6586
/>
6687
</Stack>
6788
}
@@ -82,7 +103,12 @@ export const DeleteFileDialog: FC<{
82103
open={open}
83104
onConfirm={onConfirm}
84105
title="Delete File"
85-
description={`Are you sure you want to delete "${filename}"?`}
106+
description={
107+
<>
108+
Are you sure you want to delete <strong>{filename}</strong>? It will
109+
be deleted permanently.
110+
</>
111+
}
86112
/>
87113
)
88114
}
@@ -93,9 +119,10 @@ export const RenameFileDialog: FC<{
93119
checkExists: (path: string) => boolean
94120
open: boolean
95121
filename: string
96-
}> = ({ checkExists, onClose, onConfirm, open, filename }) => {
122+
fileTree: FileTree
123+
}> = ({ checkExists, onClose, onConfirm, open, filename, fileTree }) => {
97124
const [pathValue, setPathValue] = useState(filename)
98-
const [error, setError] = useState("")
125+
const [error, setError] = useState<string>()
99126
const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
100127
setPathValue(event.target.value)
101128
}
@@ -108,7 +135,20 @@ export const RenameFileDialog: FC<{
108135
setError("File already exists")
109136
return
110137
}
138+
if (!isAllowedFile(pathValue)) {
139+
const extensions = allowedExtensions.join(", ")
140+
setError(
141+
`This extension is not allowed. You only can rename files with the following extensions: ${extensions}.`,
142+
)
143+
return
144+
}
145+
const pathError = validatePath(pathValue, fileTree)
146+
if (pathError) {
147+
setError(pathError)
148+
return
149+
}
111150
onConfirm(pathValue)
151+
setError(undefined)
112152
setPathValue("")
113153
}
114154

@@ -117,33 +157,34 @@ export const RenameFileDialog: FC<{
117157
open={open}
118158
onClose={() => {
119159
onClose()
160+
setError(undefined)
120161
setPathValue("")
121162
}}
122163
onConfirm={handleConfirm}
123164
hideCancel={false}
124165
type="success"
125166
cancelText="Cancel"
126-
confirmText="Create"
167+
confirmText="Rename"
127168
title="Rename File"
128169
description={
129-
<Stack spacing={1}>
130-
<Typography>
131-
Rename {`"${filename}"`} to something else. This path can contain
132-
slashes too!
133-
</Typography>
170+
<Stack>
171+
<p>
172+
Rename <strong>{filename}</strong> to something else. This path can
173+
contain slashes too!
174+
</p>
134175
<TextField
135176
autoFocus
136177
onKeyDown={(event) => {
137178
if (event.key === "Enter") {
138179
handleConfirm()
139180
}
140181
}}
182+
error={Boolean(error)}
141183
helperText={error}
142184
name="file-path"
143185
autoComplete="off"
144186
id="file-path"
145-
placeholder="main.tf"
146-
defaultValue={filename}
187+
placeholder={filename}
147188
value={pathValue}
148189
onChange={handleChange}
149190
label="File Path"

site/src/components/TemplateVersionEditor/FileTreeView.tsx

+4-3
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ export const FileTreeView: FC<{
6767
onSelect(currentPath)
6868
}}
6969
onContextMenu={(event) => {
70-
event.preventDefault()
70+
event.preventDefault() // Avoid default browser behavior
71+
event.stopPropagation() // Avoid trigger parent context menu
7172
setContextMenu(
7273
contextMenu
7374
? undefined
@@ -137,7 +138,7 @@ export const FileTreeView: FC<{
137138
setContextMenu(undefined)
138139
}}
139140
>
140-
Rename...
141+
Rename
141142
</MenuItem>
142143
<MenuItem
143144
onClick={() => {
@@ -148,7 +149,7 @@ export const FileTreeView: FC<{
148149
setContextMenu(undefined)
149150
}}
150151
>
151-
Delete Permanently
152+
Delete
152153
</MenuItem>
153154
</Menu>
154155
</TreeView>

site/src/components/TemplateVersionEditor/TemplateVersionEditor.tsx

+10-12
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@ import { WorkspaceBuildLogs } from "components/WorkspaceBuildLogs/WorkspaceBuild
1818
import { FC, useCallback, useEffect, useRef, useState } from "react"
1919
import { navHeight, dashboardContentBottomPadding } from "theme/constants"
2020
import {
21+
createFile,
2122
existsFile,
2223
FileTree,
2324
getFileContent,
2425
isFolder,
26+
moveFile,
2527
removeFile,
26-
setFile,
2728
traverse,
29+
updateFile,
2830
} from "util/filetree"
2931
import {
3032
CreateFileDialog,
@@ -216,13 +218,14 @@ export const TemplateVersionEditor: FC<TemplateVersionEditorProps> = ({
216218
</Tooltip>
217219
</div>
218220
<CreateFileDialog
221+
fileTree={fileTree}
219222
open={createFileOpen}
220223
onClose={() => {
221224
setCreateFileOpen(false)
222225
}}
223226
checkExists={(path) => existsFile(path, fileTree)}
224227
onConfirm={(path) => {
225-
setFileTree((fileTree) => setFile(path, "", fileTree))
228+
setFileTree((fileTree) => createFile(path, fileTree, ""))
226229
setActivePath(path)
227230
setCreateFileOpen(false)
228231
setDirty(true)
@@ -245,6 +248,7 @@ export const TemplateVersionEditor: FC<TemplateVersionEditorProps> = ({
245248
filename={deleteFileOpen || ""}
246249
/>
247250
<RenameFileDialog
251+
fileTree={fileTree}
248252
open={Boolean(renameFileOpen)}
249253
onClose={() => {
250254
setRenameFileOpen(undefined)
@@ -255,15 +259,9 @@ export const TemplateVersionEditor: FC<TemplateVersionEditorProps> = ({
255259
if (!renameFileOpen) {
256260
return
257261
}
258-
setFileTree((fileTree) => {
259-
fileTree = setFile(
260-
newPath,
261-
getFileContent(renameFileOpen, fileTree) as string,
262-
fileTree,
263-
)
264-
fileTree = removeFile(renameFileOpen, fileTree)
265-
return fileTree
266-
})
262+
setFileTree((fileTree) =>
263+
moveFile(renameFileOpen, newPath, fileTree),
264+
)
267265
setActivePath(newPath)
268266
setRenameFileOpen(undefined)
269267
setDirty(true)
@@ -294,7 +292,7 @@ export const TemplateVersionEditor: FC<TemplateVersionEditorProps> = ({
294292
return
295293
}
296294
setFileTree((fileTree) =>
297-
setFile(activePath, value, fileTree),
295+
updateFile(activePath, value, fileTree),
298296
)
299297
setDirty(true)
300298
}}

site/src/components/WorkspaceSchedule/WorkspaceSchedule.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export const WorkspaceSchedule: FC<
4646

4747
return (
4848
<div className={styles.schedule}>
49-
<Stack spacing={2}>
49+
<Stack>
5050
<div>
5151
<span className={styles.scheduleLabel}>{Language.timezoneLabel}</span>
5252
<span className={styles.scheduleValue}>{timezone}</span>

site/src/pages/WorkspaceChangeVersionPage/WorkspaceChangeVersionForm.tsx

+1-6
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,7 @@ export const WorkspaceChangeVersionForm: FC<{
3939
return (
4040
<form onSubmit={formik.handleSubmit}>
4141
<Stack direction="column" spacing={3}>
42-
<Stack
43-
direction="row"
44-
spacing={2}
45-
className={styles.workspace}
46-
alignItems="center"
47-
>
42+
<Stack direction="row" className={styles.workspace} alignItems="center">
4843
<div className={styles.workspaceIcon}>
4944
<img src={workspace.template_icon} alt="" />
5045
</div>

0 commit comments

Comments
 (0)