diff --git a/apps/showcase/package.json b/apps/showcase/package.json
index d316b78ad9..ad8b9ef13b 100644
--- a/apps/showcase/package.json
+++ b/apps/showcase/package.json
@@ -84,7 +84,7 @@
"ngx-highlightjs": "^12.0.0",
"ngx-markdown": "^18.1.0",
"ngx-monaco-editor-v2": "^18.0.0",
- "ngx-monaco-tree": "^18.1.0",
+ "ngx-monaco-tree": "^18.3.0",
"pixelmatch": "^5.2.1",
"pngjs": "^7.0.0",
"prism-themes": "^1.9.0",
diff --git a/apps/showcase/src/components/training/code-editor-view/code-editor-view.component.html b/apps/showcase/src/components/training/code-editor-view/code-editor-view.component.html
index 1a87319958..86dc89549e 100644
--- a/apps/showcase/src/components/training/code-editor-view/code-editor-view.component.html
+++ b/apps/showcase/src/components/training/code-editor-view/code-editor-view.component.html
@@ -5,7 +5,7 @@
@@ -26,7 +26,7 @@
- @if (editorMode === 'interactive') {
+ @if (editorMode() === 'interactive') {
diff --git a/apps/showcase/src/components/training/code-editor-view/code-editor-view.component.ts b/apps/showcase/src/components/training/code-editor-view/code-editor-view.component.ts
index cde520843c..022b59bd60 100644
--- a/apps/showcase/src/components/training/code-editor-view/code-editor-view.component.ts
+++ b/apps/showcase/src/components/training/code-editor-view/code-editor-view.component.ts
@@ -5,12 +5,12 @@ import {
ChangeDetectionStrategy,
Component,
computed,
+ effect,
ElementRef,
inject,
- Input,
- OnChanges,
+ input,
OnDestroy,
- SimpleChanges,
+ untracked,
ViewChild,
ViewEncapsulation,
} from '@angular/core';
@@ -119,7 +119,7 @@ export interface TrainingProject {
templateUrl: './code-editor-view.component.html',
styleUrl: './code-editor-view.component.scss'
})
-export class CodeEditorViewComponent implements OnDestroy, OnChanges {
+export class CodeEditorViewComponent implements OnDestroy {
/**
* @see {FormBuilder}
*/
@@ -142,13 +142,13 @@ export class CodeEditorViewComponent implements OnDestroy, OnChanges {
/**
* Allow to edit the code in the monaco editor
*/
- @Input() public editorMode: EditorMode = 'readonly';
+ public editorMode = input('readonly');
/**
* Project to load in the code editor.
* It should describe the files to load, the starting file, the folder dedicated to the project as well as the
* commands to initialize the project
*/
- @Input() public project?: TrainingProject;
+ public project = input.required();
/**
* Service to load files and run commands in the application instance of the webcontainer.
*/
@@ -177,9 +177,9 @@ export class CodeEditorViewComponent implements OnDestroy, OnChanges {
code: FormControl;
file: FormControl;
}> = this.formBuilder.group({
- code: '',
- file: ''
- });
+ code: '',
+ file: ''
+ });
/**
* Subject used to notify when monaco editor has been initialized
@@ -201,7 +201,7 @@ export class CodeEditorViewComponent implements OnDestroy, OnChanges {
filter((filePath): filePath is string => !!filePath),
map(() => ({
theme: 'vs-dark',
- readOnly: (this.editorMode === 'readonly'),
+ readOnly: (this.editorMode() === 'readonly'),
automaticLayout: true,
scrollBeyondLastLine: false,
overflowWidgetsDomNode: this.monacoOverflowWidgets.nativeElement,
@@ -213,7 +213,7 @@ export class CodeEditorViewComponent implements OnDestroy, OnChanges {
takeUntilDestroyed(),
combineLatestWith(this.cwdTree$),
filter(([path, monacoTree]) => !!path && checkIfPathInMonacoTree(monacoTree, path.split('/'))),
- switchMap(([path]) => from(this.webContainerService.readFile(`${this.project!.cwd}/${path}`).catch(() => ''))),
+ switchMap(([path]) => from(this.webContainerService.readFile(`${this.project().cwd}/${path}`).catch(() => ''))),
share()
);
@@ -235,6 +235,17 @@ export class CodeEditorViewComponent implements OnDestroy, OnChanges {
});
constructor() {
+ effect(async () => {
+ const project = this.project();
+ await untracked(async () => {
+ if (project.files) {
+ // Remove link between launch project and terminals
+ await this.webContainerService.loadProject(project.files, project.commands, project.cwd);
+ }
+ await this.loadNewProject();
+ this.cwd$.next(project?.cwd || '');
+ });
+ });
this.form.controls.code.valueChanges.pipe(
distinctUntilChanged(),
skip(1),
@@ -246,7 +257,7 @@ export class CodeEditorViewComponent implements OnDestroy, OnChanges {
this.loggerService.error('No project found');
return;
}
- const path = `${this.project.cwd}/${this.form.controls.file.value}`;
+ const path = `${this.project().cwd}/${this.form.controls.file.value}`;
this.loggerService.log('Writing file', path);
void this.webContainerService.writeFile(path, text);
});
@@ -268,10 +279,10 @@ export class CodeEditorViewComponent implements OnDestroy, OnChanges {
void this.monacoPromise.then((monaco) => {
monaco.editor.registerEditorOpener({
openCodeEditor: (_source: Monaco.editor.ICodeEditor, resource: Monaco.Uri, selectionOrPosition?: Monaco.IRange | Monaco.IPosition) => {
- if (resource && this.project?.files) {
+ if (resource && this.project().files) {
const filePath = resource.path.slice(1);
// TODO write a proper function to search in the tree
- const flatFiles = flattenTree(this.project.files);
+ const flatFiles = flattenTree(this.project().files);
if (flatFiles.some((projectFile) => projectFile.filePath === resource.path)) {
this.form.controls.file.setValue(filePath);
if (selectionOrPosition) {
@@ -318,7 +329,7 @@ export class CodeEditorViewComponent implements OnDestroy, OnChanges {
*/
private async loadAllProjectFilesToMonaco() {
const monaco = await this.monacoPromise;
- const flatFiles = flattenTree(this.project?.files!);
+ const flatFiles = flattenTree(this.project().files);
flatFiles.forEach(({ filePath, content }) => {
const language = editorOptionsLanguage[filePath.split('.').at(-1) || ''] || '';
monaco.editor.createModel(content, language, monaco.Uri.from({ scheme: 'file', path: filePath }));
@@ -333,23 +344,23 @@ export class CodeEditorViewComponent implements OnDestroy, OnChanges {
* Load a new project in global monaco editor and update local form accordingly
*/
private async loadNewProject() {
- await this.cleanAllModelsFromMonaco();
- await this.loadAllProjectFilesToMonaco();
- if (this.project?.startingFile) {
- this.form.controls.file.setValue(this.project.startingFile);
+ if (this.project()?.startingFile) {
+ this.form.controls.file.setValue(this.project().startingFile);
} else {
this.form.controls.file.setValue('');
this.form.controls.code.setValue('');
}
+ await this.cleanAllModelsFromMonaco();
+ await this.loadAllProjectFilesToMonaco();
}
/**
* Reload declaration types from web-container
*/
public async reloadDeclarationTypes() {
- if (this.project?.cwd) {
+ if (this.project().cwd) {
const declarationTypes = [
- ...await this.webContainerService.getDeclarationTypes(this.project.cwd),
+ ...await this.webContainerService.getDeclarationTypes(this.project().cwd),
{ filePath: 'file:///node_modules/@ama-sdk/core/index.d.ts', content: 'export * from "./src/public_api.d.ts";' },
{ filePath: 'file:///node_modules/@ama-sdk/client-fetch/index.d.ts', content: 'export * from "./src/public_api.d.ts";' }
];
@@ -370,29 +381,12 @@ export class CodeEditorViewComponent implements OnDestroy, OnChanges {
* @inheritDoc
*/
public async onClickFile(filePath: string) {
- if (!this.project) {
- return;
- }
- const path = `${this.project.cwd}/${filePath}`;
- if (this.project && await this.webContainerService.isFile(path)) {
+ const path = `${this.project().cwd}/${filePath}`;
+ if (await this.webContainerService.isFile(path)) {
this.form.controls.file.setValue(filePath);
}
}
- /**
- * @inheritDoc
- */
- public ngOnChanges(changes: SimpleChanges) {
- if ('project' in changes) {
- if (this.project?.files) {
- // Remove link between launch project and terminals
- void this.webContainerService.loadProject(this.project.files, this.project.commands, this.project.cwd);
- }
- void this.loadNewProject();
- this.cwd$.next(this.project?.cwd || '');
- }
- }
-
/**
* @inheritDoc
*/
diff --git a/package.json b/package.json
index d8e9998781..8d3eff8d24 100644
--- a/package.json
+++ b/package.json
@@ -257,7 +257,7 @@
"ngx-highlightjs": "^12.0.0",
"ngx-markdown": "^18.1.0",
"ngx-monaco-editor-v2": "^18.0.0",
- "ngx-monaco-tree": "^18.1.0",
+ "ngx-monaco-tree": "^18.3.0",
"npm-run-all2": "^6.0.0",
"nx": "~19.5.0",
"nx-cloud": "^19.1.0",
diff --git a/yarn.lock b/yarn.lock
index b6375cc7ca..c85c3cb69d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -9340,7 +9340,7 @@ __metadata:
ngx-highlightjs: "npm:^12.0.0"
ngx-markdown: "npm:^18.1.0"
ngx-monaco-editor-v2: "npm:^18.0.0"
- ngx-monaco-tree: "npm:^18.1.0"
+ ngx-monaco-tree: "npm:^18.3.0"
npm-run-all2: "npm:^6.0.0"
nx: "npm:~19.5.0"
nx-cloud: "npm:^19.1.0"
@@ -10321,7 +10321,7 @@ __metadata:
ngx-highlightjs: "npm:^12.0.0"
ngx-markdown: "npm:^18.1.0"
ngx-monaco-editor-v2: "npm:^18.0.0"
- ngx-monaco-tree: "npm:^18.1.0"
+ ngx-monaco-tree: "npm:^18.3.0"
pixelmatch: "npm:^5.2.1"
playwright-lighthouse: "npm:~4.0.0"
pngjs: "npm:^7.0.0"
@@ -28999,9 +28999,9 @@ __metadata:
languageName: node
linkType: hard
-"ngx-monaco-tree@npm:^18.1.0":
- version: 18.2.0
- resolution: "ngx-monaco-tree@npm:18.2.0"
+"ngx-monaco-tree@npm:^18.3.0":
+ version: 18.3.0
+ resolution: "ngx-monaco-tree@npm:18.3.0"
dependencies:
tslib: "npm:^2.7.0"
peerDependencies:
@@ -29009,7 +29009,7 @@ __metadata:
"@angular/common": ^18.2.2
"@angular/core": ^18.2.2
"@vscode/codicons": ^0.0.32
- checksum: 10/87044e525ebbb39612a23642dd1d7ece8b46f338e0d3467edcc429a0b26ae4ac06b6a28393443be48b0380b290e99ab6ef6655ca69c8e65bd33728c70a2724cf
+ checksum: 10/ee369bc9b313ab6cafa12c58d9502dbeb4f33df61cc2c09e5e59dfec0e87c766889ed329f01566731d84fc8fc4193c74e6b4e8b6b331ce5fff1505b531ca2154
languageName: node
linkType: hard