Add headline to tables

urls
Max Ehrlicher-Schmidt 4 years ago
parent 5b2ae731c4
commit f18da19bcc

@ -1,234 +1,244 @@
<div class="table-page-wrapper"> <div class="table-page-wrapper">
<div class="table-control"> <h1 class="headline">
<button {{ headline }}
mat-raised-button </h1>
color="primary" <div class="table-control">
class="table-control-button" <button
disabled mat-raised-button
i18n color="primary"
> class="table-control-button"
Alle ausgewählten Fahrräder bearbeiten disabled
</button> i18n
<button >
mat-raised-button Alle ausgewählten Fahrräder bearbeiten
class="table-control-button" </button>
matTooltip="Tabllendaten aktualisieren. Achtung! Alle ungespeicherten Änderungen gehen verloren." <button
(click)="reloadTable()" mat-raised-button
[disabled]="reloadingTable" class="table-control-button"
> matTooltip="Tabllendaten aktualisieren. Achtung! Alle ungespeicherten Änderungen gehen verloren."
<mat-icon class="spin">sync</mat-icon> (click)="reloadTable()"
</button> [disabled]="reloadingTable"
<button >
mat-raised-button <mat-icon class="spin">sync</mat-icon>
class="table-control-button" </button>
(click)="addNewObject()" <button
[disabled]="reloadingTable" mat-raised-button
> class="table-control-button"
<mat-icon class="spin">add</mat-icon> (click)="addNewObject()"
</button> [disabled]="reloadingTable"
<mat-form-field class="filter"> >
<mat-label>Filter</mat-label> <mat-icon class="spin">add</mat-icon>
<input </button>
matInput <mat-form-field class="filter">
[(ngModel)]="filter.includesString" <mat-label>Filter</mat-label>
(input)="applyFilter()" <input
placeholder="Suchbegriff eingeben..." matInput
/> [(ngModel)]="filter.includesString"
</mat-form-field> (input)="applyFilter()"
<button placeholder="Suchbegriff eingeben..."
*ngIf="!filter.onlyUnsaved && countUnsavedRows() > 0" />
mat-raised-button </mat-form-field>
color="accent" <button
class="table-control-button" *ngIf="!filter.onlyUnsaved && countUnsavedRows() > 0"
(click)="showOnlyUnsavedElements(true)" mat-raised-button
[disabled]="reloadingTable" color="accent"
i18n class="table-control-button"
> (click)="showOnlyUnsavedElements(true)"
{{ countUnsavedRows() }} ungespeicherte(s) Element(e) anzeigen [disabled]="reloadingTable"
</button> i18n
<mat-checkbox >
*ngIf="filter.onlyUnsaved" {{ countUnsavedRows() }} ungespeicherte(s) Element(e) anzeigen
(change)="showOnlyUnsavedElements(false)" </button>
[(ngModel)]="filter.onlyUnsaved" <mat-checkbox
> *ngIf="filter.onlyUnsaved"
nur ungespeicherte Elemente anzeigen (change)="showOnlyUnsavedElements(false)"
</mat-checkbox> [(ngModel)]="filter.onlyUnsaved"
<mat-paginator >
[pageSizeOptions]="[15, 25, 30, 50, 100]" nur ungespeicherte Elemente anzeigen
showFirstLastButtons </mat-checkbox>
></mat-paginator> <mat-paginator
</div> [pageSizeOptions]="[15, 25, 30, 50, 100]"
<div class="table-container"> showFirstLastButtons
<table ></mat-paginator>
mat-table </div>
class="mat-elevation-z8" <div class="table-container">
matSort <table
cdkDropList mat-table
cdkDropListOrientation="horizontal" class="mat-elevation-z8"
(cdkDropListDropped)="drop($event)" matSort
[dataSource]="data" cdkDropList
> cdkDropListOrientation="horizontal"
<!--- Note that these columns can be defined in any order. (cdkDropListDropped)="drop($event)"
[dataSource]="data"
>
<!--- Note that these columns can be defined in any order.
The actual rendered columns are set as a property on the row definition" --> The actual rendered columns are set as a property on the row definition" -->
<!-- Checkbox Column --> <!-- Checkbox Column -->
<ng-container matColumnDef="select" sticky> <ng-container matColumnDef="select" sticky>
<th mat-header-cell *matHeaderCellDef> <th mat-header-cell *matHeaderCellDef>
<mat-checkbox <mat-checkbox
(change)="$event ? masterToggle() : null" (change)="$event ? masterToggle() : null"
[checked]="selection.hasValue() && isAllSelected()" [checked]="selection.hasValue() && isAllSelected()"
[indeterminate]="selection.hasValue() && !isAllSelected()" [indeterminate]="selection.hasValue() && !isAllSelected()"
> >
</mat-checkbox> </mat-checkbox>
</th> </th>
<td mat-cell *matCellDef="let row"> <td mat-cell *matCellDef="let row">
<mat-checkbox <mat-checkbox
(click)="$event.stopPropagation()" (click)="$event.stopPropagation()"
(change)="$event ? selection.toggle(row) : null" (change)="$event ? selection.toggle(row) : null"
[checked]="selection.isSelected(row)" [checked]="selection.isSelected(row)"
>
</mat-checkbox>
</td>
</ng-container>
<!-- Other Columns -->
<ng-container
*ngFor="let column of columnInfo"
[matColumnDef]="column.name"
[sticky]="isStickyColumn(column.name)"
>
<!-- add cdkDrag to make columns draggable-->
<th mat-header-cell *matHeaderCellDef mat-sort-header>
{{ getTranslation(column.name) }}
</th>
<td mat-cell *matCellDef="let element">
<app-cell
*ngIf="
column.type === 'Boolean' ||
element.newObject ||
(!column.readonly && element.isLockedByMe);
else stringValue
"
[editable]="
(element.newObject && column.acceptedForCreation) ||
(!column.readonly && element.isLockedByMe)
"
[required]="element.newObject && column.requiredForCreation"
(validityChange)="validityChange(element, column.name, $event)"
[(value)]="element[column.name]"
[inputType]="column.type"
[link]="column.link ? column.link(element) : null"
></app-cell>
<ng-template #stringValue>
<span *ngIf="!column.link">{{ element[column.name] }}</span>
<a
mat-button
color="primary"
*ngIf="column.link"
[routerLink]="column.link(element)"
>{{ element[column.name] }}</a
> >
</mat-checkbox> </ng-template>
</td> </td>
</ng-container> </ng-container>
<!-- Other Columns --> <!-- Buttons Column -->
<ng-container <ng-container matColumnDef="buttons" stickyEnd>
*ngFor="let column of columnInfo" <th mat-header-cell *matHeaderCellDef></th>
[matColumnDef]="column.name" <td mat-cell *matCellDef="let element">
[sticky]="isStickyColumn(column.name)" <div class="button-wrapper" *ngIf="!element.newObject">
> <button
<!-- add cdkDrag to make columns draggable--> mat-icon-button
<th mat-header-cell *matHeaderCellDef mat-sort-header> (click)="lock(element)"
{{ getTranslation(column.name) }}
</th>
<td mat-cell *matCellDef="let element">
<app-cell
*ngIf=" *ngIf="
column.type === 'Boolean' || !element.isLockedByMe &&
element.newObject || !element.isLocked &&
(!column.readonly && element.isLockedByMe); !isLoading(element.id)
else stringValue
" "
[editable]=" >
(element.newObject && column.acceptedForCreation) || <mat-icon>edit</mat-icon>
(!column.readonly && element.isLockedByMe) </button>
<button
mat-icon-button
[matMenuTriggerFor]="menu"
*ngIf="
!element.isLockedByMe &&
!isLoading(element.id) &&
!element.isLocked
" "
[required]="element.newObject && column.requiredForCreation" >
(validityChange)="validityChange(element, column.name, $event)" <mat-icon>more_vert</mat-icon>
[(value)]="element[column.name]" </button>
[inputType]="column.type" <mat-menu #menu="matMenu">
[link]="column.link ? column.link(element) : null"
></app-cell>
<ng-template #stringValue>
<span *ngIf="!column.link">{{ element[column.name] }}</span>
<a mat-button color="primary" *ngIf="column.link" [routerLink]="column.link(element)">{{
element[column.name]
}}</a>
</ng-template>
</td>
</ng-container>
<!-- Buttons Column -->
<ng-container matColumnDef="buttons" stickyEnd>
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let element">
<div class="button-wrapper" *ngIf="!element.newObject">
<button <button
mat-icon-button mat-menu-item
(click)="lock(element)" (click)="openDeleteConfirmationDialog(element)"
*ngIf="
!element.isLockedByMe &&
!element.isLocked &&
!isLoading(element.id)
"
> >
<mat-icon>edit</mat-icon> <mat-icon>delete</mat-icon>Löschen
</button> </button>
<button <button mat-menu-item>
mat-icon-button <mat-icon>content_copy</mat-icon>Duplizieren
[matMenuTriggerFor]="menu"
*ngIf="
!element.isLockedByMe &&
!isLoading(element.id) &&
!element.isLocked
"
>
<mat-icon>more_vert</mat-icon>
</button> </button>
<mat-menu #menu="matMenu"> </mat-menu>
<button
mat-menu-item
(click)="openDeleteConfirmationDialog(element)"
>
<mat-icon>delete</mat-icon>Löschen
</button>
<button mat-menu-item>
<mat-icon>content_copy</mat-icon>Duplizieren
</button>
</mat-menu>
<mat-spinner <mat-spinner
[diameter]="32" [diameter]="32"
*ngIf="isLoading(element.id)" *ngIf="isLoading(element.id)"
></mat-spinner> ></mat-spinner>
<button <button
mat-icon-button mat-icon-button
*ngIf="element.isLockedByMe && !isLoading(element.id)" *ngIf="element.isLockedByMe && !isLoading(element.id)"
(click)="save(element)" (click)="save(element)"
> >
<mat-icon>save</mat-icon> <mat-icon>save</mat-icon>
</button> </button>
<button <button
mat-icon-button mat-icon-button
matTooltip="Alle ungespeicherten Änderungen verwerfen." matTooltip="Alle ungespeicherten Änderungen verwerfen."
*ngIf="element.isLockedByMe && !isLoading(element.id)" *ngIf="element.isLockedByMe && !isLoading(element.id)"
(click)="cancel(element)" (click)="cancel(element)"
> >
<mat-icon>cancel</mat-icon> <mat-icon>cancel</mat-icon>
</button> </button>
<mat-icon <mat-icon
*ngIf="element.isLocked" *ngIf="element.isLocked"
matTooltip="Dieser Eintrag wird gerade von einem anderen Bearbeiter editiert. Aktualisieren Sie die Tabelle, um den neuen Status abzurufen." matTooltip="Dieser Eintrag wird gerade von einem anderen Bearbeiter editiert. Aktualisieren Sie die Tabelle, um den neuen Status abzurufen."
>locked</mat-icon >locked</mat-icon
>
</div>
<div
class="button-wrapper"
*ngIf="element.newObject"
[matTooltip]="(countUnvalidFields(element) > 0) ? ('Nicht ausgefüllte Pflichtfelder (rot): ' + countUnvalidFields(element)) : 'Erstellen'"
> >
<button </div>
mat-icon-button <div
[disabled]="countUnvalidFields(element) > 0" class="button-wrapper"
(click)="create(element)" *ngIf="element.newObject"
> [matTooltip]="
<mat-icon>save</mat-icon> countUnvalidFields(element) > 0
</button> ? 'Nicht ausgefüllte Pflichtfelder (rot): ' +
<button countUnvalidFields(element)
mat-icon-button : 'Erstellen'
matTooltip="Verwerfen" "
(click)="deleteNewObject(element)" >
> <button
<mat-icon>delete</mat-icon> mat-icon-button
</button> [disabled]="countUnvalidFields(element) > 0"
</div> (click)="create(element)"
</td> >
</ng-container> <mat-icon>save</mat-icon>
</button>
<button
mat-icon-button
matTooltip="Verwerfen"
(click)="deleteNewObject(element)"
>
<mat-icon>delete</mat-icon>
</button>
</div>
</td>
</ng-container>
<!-- Table Definition --> <!-- Table Definition -->
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr> <tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr> <tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
</table> </table>
<mat-card <mat-card
*ngIf="!isLoaded" *ngIf="!isLoaded"
style="display: flex; justify-content: center; align-items: center" style="display: flex; justify-content: center; align-items: center"
> >
<mat-spinner [diameter]="32"></mat-spinner> <mat-spinner [diameter]="32"></mat-spinner>
</mat-card> </mat-card>
</div>
</div> </div>
</div>

@ -2,6 +2,9 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%; height: 100%;
.headline {
margin: 0 0.5em;
}
.table-control { .table-control {
margin: 0.5em; margin: 0.5em;
flex: none; flex: none;

@ -23,6 +23,8 @@ import { MatDialog, MatDialogRef } from '@angular/material/dialog';
styleUrls: ['./table.component.scss'], styleUrls: ['./table.component.scss'],
}) })
export class TableComponent { export class TableComponent {
@Input()
headline: string = "Keine Überschrift";
/** this array defines the columns and translations of the table and the order they are displayed */ /** this array defines the columns and translations of the table and the order they are displayed */
@Input() @Input()
columnInfo: { columnInfo: {

@ -1,4 +1,5 @@
<app-table <app-table
[headline]="headline"
[columnInfo]="columnInfo" [columnInfo]="columnInfo"
[dataService]="dataService" [dataService]="dataService"
[tableDataGQLType]="tableDataGQLType" [tableDataGQLType]="tableDataGQLType"

@ -109,16 +109,16 @@ export class BikesComponent implements OnInit {
tableDataGQLCreateInputType: string = 'CargoBikeCreateInput'; tableDataGQLCreateInputType: string = 'CargoBikeCreateInput';
tableDataGQLUpdateInputType: string = 'CargoBikeUpdateInput'; tableDataGQLUpdateInputType: string = 'CargoBikeUpdateInput';
headline = 'Lastenräder';
loadingRowIds: string[] = []; loadingRowIds: string[] = [];
constructor( constructor(private bikesService: BikesService) {}
private bikesService: BikesService
) {}
ngOnInit() { ngOnInit() {
this.dataService = this.bikesService; this.dataService = this.bikesService;
} }
create(object: {currentId: string, row: any}) { create(object: { currentId: string; row: any }) {
this.bikesService.createBike(object.currentId, { bike: object.row }); this.bikesService.createBike(object.currentId, { bike: object.row });
} }

@ -1,4 +1,5 @@
<app-table <app-table
[headline]="headline"
[columnInfo]="columnInfo" [columnInfo]="columnInfo"
[dataService]="dataService" [dataService]="dataService"
[tableDataGQLType]="tableDataGQLType" [tableDataGQLType]="tableDataGQLType"

@ -7,6 +7,8 @@ import {EquipmentTypeService} from 'src/app/services/equipmentType.service'
styleUrls: ['./equipment-types.component.scss'] styleUrls: ['./equipment-types.component.scss']
}) })
export class EquipmentTypesComponent implements OnInit { export class EquipmentTypesComponent implements OnInit {
headline = 'Ausstattungstypen';
columnInfo = [ columnInfo = [
{ name: 'id', translation: 'ID', readonly: true }, { name: 'id', translation: 'ID', readonly: true },
{ name: 'name', translation: 'Name', requiredForCreation: true }, { name: 'name', translation: 'Name', requiredForCreation: true },

Loading…
Cancel
Save