corregida edicion de menus #85
|
|
@ -1,5 +1,9 @@
|
|||
# Changelog
|
||||
|
||||
## [1.5.6] - 2026-05-05
|
||||
### Fixed
|
||||
- Corregida edicion de menus
|
||||
|
||||
## [1.5.5] - 2026-05-04
|
||||
### Fixed
|
||||
- Corregida gestion de oglives
|
||||
|
|
|
|||
|
|
@ -32,12 +32,43 @@
|
|||
gap: 10px;
|
||||
}
|
||||
|
||||
.iframe {
|
||||
.iframe-wrapper {
|
||||
width: 100%;
|
||||
height: 600px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
|
||||
background: #000;
|
||||
}
|
||||
|
||||
.iframe-wrapper.scroll-view {
|
||||
height: 600px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.iframe-wrapper.global-view {
|
||||
aspect-ratio: 4 / 3;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.iframe {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.iframe.scroll-view {
|
||||
width: 1280px;
|
||||
height: 1024px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.iframe.global-view {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 250%;
|
||||
height: 250%;
|
||||
transform: scale(0.4);
|
||||
transform-origin: 0 0;
|
||||
}
|
||||
|
||||
.editor-controls {
|
||||
|
|
|
|||
|
|
@ -64,6 +64,10 @@
|
|||
<button type="button" class="submit-button apply-btn" (click)="applyHtmlChanges()">
|
||||
{{ 'buttonApplyChanges' | translate }}</button>
|
||||
} @else if (safeUrl) {
|
||||
<button type="button" class="ordinary-button edit-btn" (click)="toggleGlobalView()" title="Alternar vista">
|
||||
<mat-icon>{{ isGlobalView ? 'zoom_in' : 'visibility' }}</mat-icon>
|
||||
{{ isGlobalView ? 'Vista detalle' : 'Vista global' }}
|
||||
</button>
|
||||
<button type="button" class="ordinary-button edit-btn" (click)="editHtml()">
|
||||
<mat-icon>edit</mat-icon> {{ 'buttonEditHtml' | translate }}</button>
|
||||
}
|
||||
|
|
@ -73,7 +77,9 @@
|
|||
@if (isEditingHtml) {
|
||||
<textarea class="html-editor" [(ngModel)]="htmlEditorContent" spellcheck="false"></textarea>
|
||||
} @else if (safeUrl) {
|
||||
<iframe [src]="safeUrl" class="iframe"></iframe>
|
||||
<div class="iframe-wrapper" [ngClass]="{'global-view': isGlobalView, 'scroll-view': !isGlobalView}">
|
||||
<iframe [src]="safeUrl" class="iframe" [ngClass]="{'global-view': isGlobalView, 'scroll-view': !isGlobalView}"></iframe>
|
||||
</div>
|
||||
}
|
||||
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ export class CreateMenuComponent implements OnInit {
|
|||
fileContent: string | null = null;
|
||||
isEditingHtml: boolean = false;
|
||||
htmlEditorContent: string = '';
|
||||
isGlobalView: boolean = false;
|
||||
|
||||
constructor(
|
||||
private fb: FormBuilder,
|
||||
|
|
@ -120,8 +121,21 @@ export class CreateMenuComponent implements OnInit {
|
|||
// Ask the backend to compile a preview using this encoded Twig
|
||||
this.dataService.previewMenuTemplate(base64Content).subscribe({
|
||||
next: (renderedHtml) => {
|
||||
// Ensure relative paths work in the data URL iframe by injecting a <base> tag
|
||||
const origin = new URL(this.baseUrl).origin;
|
||||
const baseTag = `<base href="${origin}/">`;
|
||||
|
||||
let finalHtml = renderedHtml;
|
||||
if (finalHtml.toLowerCase().includes('<head>')) {
|
||||
finalHtml = finalHtml.replace(/<head>/i, `<head>${baseTag}`);
|
||||
} else if (finalHtml.toLowerCase().includes('<html>')) {
|
||||
finalHtml = finalHtml.replace(/<html>/i, `<html><head>${baseTag}</head>`);
|
||||
} else {
|
||||
finalHtml = `<head>${baseTag}</head>` + finalHtml;
|
||||
}
|
||||
|
||||
// Now encode the definitively rendered HTML to Base64 to populate the iframe preview
|
||||
const renderedBytes = new TextEncoder().encode(renderedHtml);
|
||||
const renderedBytes = new TextEncoder().encode(finalHtml);
|
||||
const renderedBinaryStr = Array.from(renderedBytes).map(byte => String.fromCharCode(byte)).join('');
|
||||
const renderedBase64 = window.btoa(renderedBinaryStr);
|
||||
|
||||
|
|
@ -149,6 +163,10 @@ export class CreateMenuComponent implements OnInit {
|
|||
this.htmlEditorContent = '';
|
||||
}
|
||||
|
||||
toggleGlobalView(): void {
|
||||
this.isGlobalView = !this.isGlobalView;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (this.data) {
|
||||
this.load()
|
||||
|
|
@ -183,6 +201,18 @@ export class CreateMenuComponent implements OnInit {
|
|||
isDefault: this.menuForm.value.isDefault,
|
||||
};
|
||||
|
||||
// Si el usuario le da a Guardar mientras está editando el HTML (sin haberle dado a Aplicar Cambios),
|
||||
// guardamos automáticamente lo que haya en el editor de texto.
|
||||
if (this.isEditingHtml && this.htmlEditorContent) {
|
||||
try {
|
||||
const bytes = new TextEncoder().encode(this.htmlEditorContent);
|
||||
const binaryStr = Array.from(bytes).map(byte => String.fromCharCode(byte)).join('');
|
||||
this.fileContent = window.btoa(binaryStr);
|
||||
} catch (e) {
|
||||
console.error('Failed to encode HTML content before saving', e);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.fileContent) {
|
||||
payload.menuHtmlContent = this.fileContent;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@
|
|||
"busyEquipments": "Equips Ocupats",
|
||||
"buttonAccept": "Acceptar",
|
||||
"buttonAdd": "Afegir",
|
||||
"buttonApplyChanges": "Aplicar Canvis",
|
||||
"buttonApplyChanges": "Previsualitzar",
|
||||
"buttonCancel": "Cancel·lar",
|
||||
"buttonCancelEdit": "Cancel·lar Edició",
|
||||
"buttonCancelEn": "Cancel·lar",
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@
|
|||
"busyEquipments": "Busy Equipment",
|
||||
"buttonAccept": "Accept",
|
||||
"buttonAdd": "Add",
|
||||
"buttonApplyChanges": "Apply Changes",
|
||||
"buttonApplyChanges": "Preview",
|
||||
"buttonCancel": "Cancel",
|
||||
"buttonCancelEdit": "Cancel Edit",
|
||||
"buttonCancelEn": "Cancel",
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@
|
|||
"busyEquipments": "Equipos Ocupados",
|
||||
"buttonAccept": "Aceptar",
|
||||
"buttonAdd": "Añadir",
|
||||
"buttonApplyChanges": "Aplicar Cambios",
|
||||
"buttonApplyChanges": "Previsualizar",
|
||||
"buttonCancel": "Cancelar",
|
||||
"buttonCancelEdit": "Cancelar Edición",
|
||||
"buttonCancelEn": "Cancelar",
|
||||
|
|
|
|||
Loading…
Reference in New Issue