Skip to content

Commit 0a33a18

Browse files
authored
docs(docs-infra): fix code editor file creation and renaming
Hide the field when the user unfocuses from it; Fill the input with the file name when renaming; Fix file path renaming
1 parent 2ead438 commit 0a33a18

File tree

3 files changed

+36
-33
lines changed

3 files changed

+36
-33
lines changed

adev/src/app/editor/code-editor/code-editor.component.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,14 @@
1111
<mat-tab #tab>
1212
<ng-template mat-tab-label>
1313
@if (tab.isActive && isRenamingFile()) {
14-
<form
15-
(submit)="renameFile($event, file.filename)"
16-
(docsClickOutside)="closeRenameFile()"
17-
>
14+
<form (submit)="renameFile($event, file.filename)">
1815
<input
1916
name="rename-file"
2017
class="adev-rename-file-input"
18+
[value]="file.filename.replace('src/', '')"
2119
#renameFileInput
2220
(keydown)="$event.stopPropagation()"
21+
(blur)="isRenamingFile.set(false)"
2322
/>
2423
</form>
2524
} @else if (restrictedMode()) {
@@ -64,6 +63,7 @@
6463
class="adev-new-file-input"
6564
#createFileInput
6665
(keydown)="$event.stopPropagation()"
66+
(blur)="createFile()"
6767
/>
6868
</form>
6969
</ng-template>

adev/src/app/editor/code-editor/code-editor.component.ts

Lines changed: 21 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import {CodeMirrorEditor} from './code-mirror-editor.service';
3232
import {DiagnosticWithLocation, DiagnosticsState} from './services/diagnostics-state.service';
3333
import {DownloadManager} from '../download-manager.service';
3434
import {StackBlitzOpener} from '../stackblitz-opener.service';
35-
import {ClickOutside, IconComponent} from '@angular/docs';
35+
import {IconComponent} from '@angular/docs';
3636
import {CdkMenu, CdkMenuItem, CdkMenuTrigger} from '@angular/cdk/menu';
3737
import {FirebaseStudioLauncher} from '../firebase-studio-launcher.service';
3838
import {MatTooltip} from '@angular/material/tooltip';
@@ -51,15 +51,7 @@ const ANGULAR_DEV = 'https://angular.dev';
5151
templateUrl: './code-editor.component.html',
5252
styleUrls: ['./code-editor.component.scss'],
5353
changeDetection: ChangeDetectionStrategy.OnPush,
54-
imports: [
55-
MatTabsModule,
56-
MatTooltip,
57-
IconComponent,
58-
ClickOutside,
59-
CdkMenu,
60-
CdkMenuItem,
61-
CdkMenuTrigger,
62-
],
54+
imports: [MatTabsModule, MatTooltip, IconComponent, CdkMenu, CdkMenuItem, CdkMenuTrigger],
6355
})
6456
export class CodeEditor {
6557
readonly restrictedMode = input(false);
@@ -155,10 +147,6 @@ export class CodeEditor {
155147
this.displayErrorsBox.set(false);
156148
}
157149

158-
protected closeRenameFile(): void {
159-
this.isRenamingFile.set(false);
160-
}
161-
162150
protected canRenameFile = (filename: string) => this.canDeleteFile(filename);
163151

164152
protected canDeleteFile(filename: string) {
@@ -189,12 +177,7 @@ export class CodeEditor {
189177

190178
const renameFileInputValue = renameFileInput.nativeElement.value;
191179

192-
if (renameFileInputValue) {
193-
if (renameFileInputValue.includes('..')) {
194-
alert('File name can not contain ".."');
195-
return;
196-
}
197-
180+
if (this.validateFileName(renameFileInputValue)) {
198181
// src is hidden from users, here we manually add it to the new filename
199182
const newFile = 'src/' + renameFileInputValue;
200183

@@ -209,20 +192,15 @@ export class CodeEditor {
209192
this.isRenamingFile.set(false);
210193
}
211194

212-
protected async createFile(event: SubmitEvent) {
195+
protected async createFile(event?: SubmitEvent) {
213196
const fileInput = this.createFileInputRef();
214197
if (!fileInput) return;
215198

216-
event.preventDefault();
199+
event?.preventDefault();
217200

218201
const newFileInputValue = fileInput.nativeElement.value;
219202

220-
if (newFileInputValue) {
221-
if (newFileInputValue.includes('..')) {
222-
alert('File name can not contain ".."');
223-
return;
224-
}
225-
203+
if (this.validateFileName(newFileInputValue)) {
226204
// src is hidden from users, here we manually add it to the new filename
227205
const newFile = 'src/' + newFileInputValue;
228206

@@ -237,6 +215,21 @@ export class CodeEditor {
237215
this.isCreatingFile.set(false);
238216
}
239217

218+
private validateFileName(fileName: string): boolean {
219+
if (!fileName) {
220+
return false;
221+
}
222+
if (fileName.split('/').pop()?.indexOf('.') === 0) {
223+
alert('File must contain a name.');
224+
return false;
225+
}
226+
if (fileName.includes('..')) {
227+
alert('File name can not contain ".."');
228+
return false;
229+
}
230+
return true;
231+
}
232+
240233
private listenToDiagnosticsChange(): void {
241234
this.errors$.subscribe((diagnostics) => {
242235
this.errors.set(diagnostics);

adev/src/app/editor/node-runtime-sandbox.service.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,17 @@ export class NodeRuntimeSandbox {
274274
try {
275275
await webContainer.fs.rename(oldPath, newPath);
276276
} catch (err: any) {
277-
throw err;
277+
if (err.message.startsWith('ENOENT')) {
278+
const directory = newPath.split('/').slice(0, -1).join('/');
279+
280+
await webContainer.fs.mkdir(directory, {
281+
recursive: true,
282+
});
283+
284+
await webContainer.fs.rename(oldPath, newPath);
285+
} else {
286+
throw err;
287+
}
278288
}
279289
}
280290

0 commit comments

Comments
 (0)