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, 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';
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
@Component({
selector: 'aspect-table',
standalone: true,
imports: [
SharedModule,
TableChildOverlay,
MatMenuModule,
MeasurePipe
],
template: `
<div [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'">
<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"
[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">
<button *ngIf="editorMode" class="delete-button" mat-mini-fab color="primary"
(click)="removeElement(i, j)">
<mat-icon>remove</mat-icon>
</button>
<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>
</div>
</div>
</ng-container>
</div>
`,
styles: [`
.cell-container {display: flex; align-items: center; justify-content: center; min-height: 50px; min-width: 50px;}
.delete-button {position: absolute; opacity: 0;}
.element-container:hover .delete-button {opacity: 1;}
.element-container {width: 100%; height: 100%; display: flex; justify-content: center;}
aspect-table-child-overlay {width: 100%; height: 100%;}
`]
})
export class TableComponent extends CompoundElementComponent implements OnInit {
@Input() elementModel!: TableElement;
@Input() savedPlaybackTimes!: { [key: string]: number };
@Input() actualPlayingId!: Subject<string | null>;
@Input() mediaStatusChanged!: Subject<string>;
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
@Input() editorMode: boolean = false;
@Output() elementAdded = new EventEmitter<{ elementType: UIElementType, row: number, col: number }>();
@Output() elementRemoved = new EventEmitter<number>();
@Output() childElementSelected = new EventEmitter<TableChildOverlay>();
@ViewChildren(TableChildOverlay) compoundChildren!: QueryList<TableChildOverlay>;
elementGrid: (PositionedUIElement | 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.position.gridRow as number) - 1][(el.position.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(this.elementGrid.flat()
.findIndex(el => el?.position.gridRow === row && el?.position.gridColumn === col));
this.refresh();
}
}