Newer
Older
import { CompoundElementComponent } from 'common/directives/compound-element.directive';
import { TableElement } from 'common/models/elements/compound-elements/table/table';
import {
Component, OnInit,
Input, Output, EventEmitter,
QueryList, ViewChildren
} from '@angular/core';
import { ElementComponent } from 'common/directives/element-component.directive';
import { SharedModule } from 'common/shared.module';
import { PositionedUIElement, UIElement, UIElementType } from 'common/models/elements/element';
import { TableChildOverlay } from 'common/components/compound-elements/table/table-child-overlay.component';
import { MatMenuModule } from '@angular/material/menu';
import { MeasurePipe } from 'common/pipes/measure.pipe';
import { Subject } from 'rxjs';
@Component({
selector: 'aspect-table',
standalone: true,
imports: [
SharedModule,
TableChildOverlay,
MatMenuModule,
MeasurePipe
],
template: `
<div class="grid-container" [style.display]="'grid'"
[style.grid-template-columns]="elementModel.gridColumnSizes | measure"
[style.grid-template-rows]="elementModel.gridRowSizes | measure"
[style.grid-auto-columns]="'auto'"
[style.grid-auto-rows]="'auto'"
[style.background-color]="elementModel.styling.backgroundColor">
<ng-container *ngFor="let row of elementGrid; let i = index;">
<div *ngFor="let column of row; let j = index;"
class="cell-container"
[style.border-style]="elementModel.styling.borderStyle"
[style.border-top-style]="(!elementModel.tableEdgesEnabled && i === 0) || (i > 0) ?
'none' : elementModel.styling.borderStyle"
[style.border-bottom-style]="(!elementModel.tableEdgesEnabled && i === elementGrid.length - 1) ?
'none' : elementModel.styling.borderStyle"
[style.border-left-style]="(!elementModel.tableEdgesEnabled && j === 0) || (j > 0) ?
'none' : elementModel.styling.borderStyle"
[style.border-right-style]="(!elementModel.tableEdgesEnabled && j === row.length - 1) ?
'none' : elementModel.styling.borderStyle"
[style.border-width.px]="elementModel.styling.borderWidth"
[style.border-color]="elementModel.styling.borderColor"
[style.border-radius.px]="elementModel.styling.borderRadius"
[style.grid-row-start]="i + 1"
[style.grid-column-start]="j + 1">
<ng-container *ngIf="elementGrid[i][j] === undefined && editorMode">
<button mat-mini-fab color="primary" class="button"
[matMenuTriggerFor]="menu">
<mat-icon>add</mat-icon>
</button>
<mat-menu #menu="matMenu">
<button mat-menu-item (click)="addElement('text', i, j)">Text</button>
<button mat-menu-item (click)="addElement('text-field', i, j)">Eingabefeld</button>
<button mat-menu-item (click)="addElement('checkbox', i, j)">Kontrollkästchen</button>
<button mat-menu-item (click)="addElement('drop-list', i, j)">Ablegeliste</button>
<button mat-menu-item (click)="addElement('image', i, j)">Bild</button>
<button mat-menu-item (click)="addElement('audio', i, j)">Audio</button>
</mat-menu>
</ng-container>
<div *ngIf="elementGrid[i][j] !== undefined" class="element-container">
<aspect-table-child-overlay [element]="$any(elementGrid[i][j])"
[parentForm]="parentForm"
[savedPlaybackTimes]="savedPlaybackTimes"
[mediaStatusChanged]="mediaStatusChanged"
[actualPlayingId]="actualPlayingId"
(elementSelected)="childElementSelected.emit($event)">
</aspect-table-child-overlay>
<button *ngIf="editorMode" class="remove-button" mat-mini-fab color="primary"
(click)="removeElement(i, j)">
<mat-icon>remove</mat-icon>
</button>
</div>
</div>
</ng-container>
</div>
`,
styles: [`
.cell-container {display: flex; min-height: 30px;}
.element-container {width: 100%; height: 100%; position: relative;}
.cell-container > button {align-self: flex-end; justify-self: flex-start;}
aspect-table-child-overlay {width: 100%; height: 100%;}
.remove-button {position: absolute; bottom: 0;}
`]
})
export class TableComponent extends CompoundElementComponent implements OnInit {
@Input() elementModel!: TableElement;
@Input() savedPlaybackTimes!: { [key: string]: number };
@Input() savedTexts!: { [key: string]: string };
@Input() actualPlayingId!: Subject<string | null>;
@Input() mediaStatusChanged!: Subject<string>;
@Input() editorMode: boolean = false;
@Output() elementAdded = new EventEmitter<{ elementType: UIElementType, row: number, col: number }>();
@Output() elementRemoved = new EventEmitter<{ row: number, col: number }>();
@Output() childElementSelected = new EventEmitter<TableChildOverlay>();
@ViewChildren(TableChildOverlay) compoundChildren!: QueryList<TableChildOverlay>;
elementGrid: (UIElement | undefined)[][] = [];
ngOnInit(): void {
this.initElementGrid();
}
private initElementGrid(): void {
this.elementGrid = new Array(this.elementModel.gridRowSizes.length).fill(undefined)
.map(() => new Array(this.elementModel.gridColumnSizes.length).fill(undefined));
this.elementModel.elements.forEach(el => {
this.elementGrid[(el.gridRow as number) - 1][(el.gridColumn as number) - 1] = el;
});
}
addElement(elementType: UIElementType, row: number, col: number): void {
this.elementAdded.emit({ elementType, row, col });
}
getFormElementChildrenComponents(): ElementComponent[] {
return this.compoundChildren.toArray().map((child: TableChildOverlay) => child.childComponent.instance);
}
refresh(): void {
this.initElementGrid();
}
removeElement(row: number, col: number): void {
this.elementRemoved.emit({ row: row, col: col });