Add editor features
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/pr Build is passing Details

pull/4/head
Hugo PRADIER 1 year ago
parent a17d97c050
commit 0c5adc9d6f

@ -35,10 +35,14 @@
id="language" id="language"
name="language" name="language"
[(ngModel)]="mode" [(ngModel)]="mode"
(ngModelChange)="changeMode()" (ngModelChange)="changeMode()">
>
<option value="text/typescript">TypeScript</option> <option value="text/typescript" selected>TypeScript</option>
<option value="markdown">Markdown</option> <option value="text/javascript">JavaScript</option>
<option value="text/x-csrc">C</option>
<option value="text/x-c++src">C++</option>
<option value="text/x-sh">Shell</option>
</select> </select>
</div> </div>
@ -51,4 +55,17 @@
<p>Chargement: {{ loadingProgress }}%</p> <p>Chargement: {{ loadingProgress }}%</p>
<div class="loading-bar" [style.width.%]="loadingProgress"></div> <div class="loading-bar" [style.width.%]="loadingProgress"></div>
</div> </div>
<div>
<label for="fileInput">Charger à partir d'un fichier</label>
<input type="file" id="fileInput" (change)="loadFromFile($event)" />
</div>
<div>
<button type="button" (click)="saveToFile()">Sauvegarder</button>
</div>
<div *ngIf="errorMessage">
<p style="color: red">{{ errorMessage }}</p>
</div>
</div> </div>

@ -2,44 +2,68 @@ import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { CodeExecutionService } from 'src/app/services/codeExecution.service'; import { CodeExecutionService } from 'src/app/services/codeExecution.service';
// Exemple de code pour chaque langage // Exemple de code pour chaque langage autorisé
const defaults = { const codeDefaults = {
markdown:
'# Sankasten\n\nProjet **SAE 3A** par _FRIZOT, MAZINGUE, OLLIER, FREVILLE ET PRADIER_ text\nGit [Sankasten WEB](https://codefirst.iut.uca.fr/git/sandkasten/sandkasten-web.git)',
'text/typescript': `const component = { 'text/typescript': `const component = {
name: "@exemple/Typescript", name: "@exemple/Typescript",
author: "Sandkasten", author: "Sandkasten",
repo: "https://codefirst.iut.uca.fr/git/sandkasten/sandkasten-web.git" repo: "https://codefirst.iut.uca.fr/git/sandkasten/sandkasten-web.git"
};
const hello: string = 'Bonjour ceci est un test de code en typescript';`
}; };
const hello: string = 'Bonjour ceci est un test de code en typescript';`,
'text/javascript': `const component = {
name: "@exemple/Javascript",
author: "Sandkasten",
repo: "https://codefirst.iut.uca.fr/git/sandkasten/sandkasten-web.git"
};
const hello = 'Bonjour ceci est un test de code en javascript';`,
'text/x-c++src': `#include <iostream>
using namespace std;
int main() {
cout << "Bonjour ceci est un test de code en c++" << endl;
return 0;
}`,
'text/x-csrc': `#include <stdio.h>
int main() {
printf("Bonjour ceci est un test de code en c");
return 0;
}`,
'text/x-sh': `#!/bin/bash
echo "Bonjour ceci est un test de code en shell"`
};
// Langages autorisés
type AllowedLanguage = 'text/x-sh' | 'text/javascript' | 'text/typescript' | 'text/x-c++src' | 'text/x-csrc';
@Component({ @Component({
selector: 'app-editor', selector: 'app-editor',
templateUrl: './editor.component.html', templateUrl: './editor.component.html',
styleUrls: ['./editor.component.scss'] styleUrls: ['./editor.component.scss']
}) })
export class EditorComponent implements OnInit{ export class EditorComponent implements OnInit {
loadingProgress: number = 0; // Pour suivre la progression du chargement loadingProgress: number = 0; // Pour suivre la progression du chargement
isLoaded: boolean = false; // Pour vérifier si le chargement est terminé isLoaded: boolean = false; // Pour vérifier si le chargement est terminé
// Mode par défaut // Mode par défaut
mode: keyof typeof defaults = 'text/typescript'; mode: AllowedLanguage = 'text/typescript';
options = { options = {
lineNumbers: true, lineNumbers: true,
mode: this.mode, mode: this.mode,
}; };
defaults = defaults; defaults = codeDefaults;
// Contenu de l'éditeur que l'on passera au serveur // Contenu de l'éditeur que l'on passera au serveur
editorContent: string = defaults[this.mode]; editorContent: string = this.defaults[this.mode as keyof typeof codeDefaults];
resultContent: string = defaults[this.mode]; resultContent: string = '';
constructor(private router: Router, private codeExecutionService: CodeExecutionService) {} // Message d'erreur
errorMessage: string = '';
ngOnInit(): void { constructor(private router: Router, private codeExecutionService: CodeExecutionService) {
}
ngOnInit(): void {
// Appel à changeMode pour mettre à jour le contenu de l'éditeur et le mode
this.changeMode();
} }
// Change le langage de l'éditeur // Change le langage de l'éditeur
@ -48,6 +72,7 @@ export class EditorComponent implements OnInit{
...this.options, ...this.options,
mode: this.mode, mode: this.mode,
}; };
this.editorContent = this.defaults[this.mode as keyof typeof codeDefaults];
} }
// Affiche le contenu de l'éditeur // Affiche le contenu de l'éditeur
@ -57,7 +82,70 @@ export class EditorComponent implements OnInit{
// Efface le contenu de l'éditeur // Efface le contenu de l'éditeur
clear(): void { clear(): void {
this.defaults[this.mode] = ''; this.editorContent = '';
}
loadFromFile(event: any): void {
const file = event.target.files[0];
if (file) {
const allowedExtensions = ['sh', 'js', 'ts', 'cpp', 'c'];
const extension = file.name.split('.').pop()?.toLowerCase();
if (extension && allowedExtensions.includes(extension)) {
// Identifiez le mode en fonction de l'extension
const modeMap: Record<string, AllowedLanguage> = {
'sh': 'text/x-sh',
'js': 'text/javascript',
'ts': 'text/typescript',
'cpp': 'text/x-c++src',
'c': 'text/x-csrc'
};
this.mode = modeMap[extension];
// Mettez à jour le contenu de l'éditeur et le mode
this.changeMode();
const reader = new FileReader();
reader.onload = (e) => {
this.editorContent = e.target?.result as string;
this.errorMessage = ''; // Réinitialisez le message d'erreur en cas de succès.
};
reader.readAsText(file);
} else {
this.errorMessage = 'Unsupported file type. Please select a file with one of the following extensions: sh, js, ts, cpp, c';
console.error(this.errorMessage);
}
}
}
saveToFile(): void {
const languageExtensionMap: Record<AllowedLanguage, string> = {
"text/x-sh" : 'sh',
"text/javascript": 'js',
"text/typescript": 'ts',
"text/x-c++src" : 'cpp',
"text/x-csrc": 'c'
};
if (languageExtensionMap[this.mode]) {
const extension = languageExtensionMap[this.mode];
if (this.editorContent.trim() === '') {
this.errorMessage = 'Cannot save an empty file.';
console.error(this.errorMessage);
} else {
this.errorMessage = ''; // Réinitialisez le message d'erreur en cas de succès.
const blob = new Blob([this.editorContent], { type: 'text/plain' });
const a = document.createElement('a');
a.href = window.URL.createObjectURL(blob);
a.download = `code.${extension}`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
} else {
this.errorMessage = 'Unsupported language. Please select one of the following languages: shell, javascript, typescript, c++, c';
console.error(this.errorMessage);
}
} }
onRunButtonClicked() { onRunButtonClicked() {

Loading…
Cancel
Save