Se ha mejorado el editor de menus para poder editar directamente la plantilla twig en lugar del html renderizado.
testing/ogGui-multibranch/pipeline/head There was a failure building this commit Details
testing/ogGui-multibranch/pipeline/pr-main Build started... Details

pull/55/head
Juan Manuel Bardallo 2026-03-25 15:04:07 +01:00
parent efee90bd3e
commit e259315765
3 changed files with 53 additions and 13 deletions

View File

@ -1,4 +1,8 @@
# Changelog
## [1.2.4] - 2026-03-20
### Added
- Se ha mejorado el editor de menus para poder editar directamente la plantilla twig en lugar del html renderizado.
## [1.2.3] - 2026-03-17
### Added
- Se ha creado una nueva opción para gestionar assets en la pantalla de menus.

View File

@ -88,15 +88,15 @@ export class CreateMenuComponent implements OnInit {
}
this.isEditingHtml = true;
} else if (this.menuForm.get('publicUrl')?.value) {
// Fetch the actual HTML from the public URL if it exists and no file was manually uploaded yet
const url = `${this.baseUrl}/menu/${this.menuForm.get('publicUrl')?.value}`;
this.http.get(url, { responseType: 'text' }).subscribe({
// Fetch the actual raw HTML/Twig template if it exists and no file was manually uploaded yet
const publicUrl = this.menuForm.get('publicUrl')?.value;
this.dataService.getRawMenuTemplate(publicUrl).subscribe({
next: (htmlStr) => {
this.htmlEditorContent = htmlStr;
this.isEditingHtml = true;
},
error: (err) => {
this.toastService.error('No se pudo descargar el HTML actual del menú para editarlo.');
this.toastService.error('No se pudo descargar el HTML/Twig original del menú para editarlo.');
console.error(err);
}
});
@ -105,22 +105,38 @@ export class CreateMenuComponent implements OnInit {
applyHtmlChanges(): void {
if (this.htmlEditorContent) {
// Encode the typed text back into Base64 enforcing UTF-8 compatibility
// Encode the drafted Twig code back into Base64 enforcing UTF-8 compatibility
try {
// Modern approach to encode UTF-8 string to Base64
const bytes = new TextEncoder().encode(this.htmlEditorContent);
const binaryStr = Array.from(bytes).map(byte => String.fromCharCode(byte)).join('');
this.fileContent = window.btoa(binaryStr);
const base64Content = window.btoa(binaryStr);
// This holds the RAW twig that will be sent via PUT/POST on save
this.fileContent = base64Content;
// Ask the backend to compile a preview using this encoded Twig
this.dataService.previewMenuTemplate(base64Content).subscribe({
next: (renderedHtml) => {
// Now encode the definitively rendered HTML to Base64 to populate the iframe preview
const renderedBytes = new TextEncoder().encode(renderedHtml);
const renderedBinaryStr = Array.from(renderedBytes).map(byte => String.fromCharCode(byte)).join('');
const renderedBase64 = window.btoa(renderedBinaryStr);
this.isEditingHtml = false;
const dataUrl = `data:text/html;base64,${renderedBase64}`;
this.safeUrl = this.sanitizer.bypassSecurityTrustResourceUrl(dataUrl);
this.toastService.success('Vista previa generada. Pulsa Guardar para aplicar la plantilla remota permanentemente.');
},
error: (err) => {
console.error('Failed to preview generated HTML', err);
const msg = err.error?.message || 'Error compilando la plantilla Twig.';
this.toastService.error(msg);
}
});
// Switch to preview mode and update the iframe source to use the fresh Base64
this.isEditingHtml = false;
const dataUrl = `data:text/html;base64,${this.fileContent}`;
this.safeUrl = this.sanitizer.bypassSecurityTrustResourceUrl(dataUrl);
this.toastService.success('Cambios aplicados temporalmente. Pulsa Guardar para subirlos al servidor.');
} catch (e) {
console.error('Failed to encode updated HTML to Base64', e);
this.toastService.error('Hubo un problema procesando los caracteres especiales del HTML.');
// En caso de error, nos mantenemos en la vista de edición para que el usuario pueda corregirlo
}
}
}

View File

@ -16,6 +16,26 @@ export class DataService {
this.apiUrl = `${this.baseUrl}/menus?page=1&itemsPerPage=1000`;
}
getRawMenuTemplate(publicUrl: string): Observable<string> {
const url = `${this.baseUrl}/menu-raw/${publicUrl}`;
return this.http.get(url, { responseType: 'text' }).pipe(
catchError(error => {
console.error('Error fetching raw menu template', error);
return throwError(() => error);
})
);
}
previewMenuTemplate(base64Template: string): Observable<string> {
const url = `${this.baseUrl}/menu-preview`;
return this.http.post(url, { templateBase64: base64Template }, { responseType: 'text' }).pipe(
catchError(error => {
console.error('Error previewing menu template', error);
return throwError(() => error);
})
);
}
getMenus(filters: { [key: string]: string }): Observable<{ totalItems: any; data: any }> {
const params = new HttpParams({ fromObject: filters });