Add cell component

pull/1/head
Max Ehrlicher-Schmidt 4 years ago
parent 4a466a9531
commit ac6af032f2

@ -31,6 +31,7 @@ import { GraphQLModule } from './graphql.module';
import { ParticipantsComponent } from './pages/tables/participants/participants.component'; import { ParticipantsComponent } from './pages/tables/participants/participants.component';
import { LendingStationsComponent } from './pages/tables/lending-stations/lending-stations.component'; import { LendingStationsComponent } from './pages/tables/lending-stations/lending-stations.component';
import { TableOverviewComponent } from './pages/table-overview/table-overview.component'; import { TableOverviewComponent } from './pages/table-overview/table-overview.component';
import { StringCellComponent } from './components/tableComponents/string-cell/string-cell.component';
@ -41,7 +42,8 @@ import { TableOverviewComponent } from './pages/table-overview/table-overview.co
BikesComponent, BikesComponent,
ParticipantsComponent, ParticipantsComponent,
LendingStationsComponent, LendingStationsComponent,
TableOverviewComponent TableOverviewComponent,
StringCellComponent
], ],
imports: [ imports: [
BrowserModule, BrowserModule,

@ -0,0 +1,6 @@
<mat-form-field *ngIf="editable; else nonEditableText">
<input matInput [type]="inputType" [ngModel]="value" (ngModelChange)="change($event)"/>
</mat-form-field>
<ng-template #nonEditableText>
{{ value }}
</ng-template>

@ -0,0 +1,21 @@
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-string-cell',
templateUrl: './string-cell.component.html',
styleUrls: ['./string-cell.component.scss'],
})
export class StringCellComponent {
@Input()
value: number | string;
@Output() valueChange = new EventEmitter<number | string>();
@Input()
editable = false;
@Input()
inputType = 'text';
change(newValue) {
this.value = newValue;
this.valueChange.emit(newValue);
}
}

@ -38,13 +38,11 @@
<!-- Name Column --> <!-- Name Column -->
<ng-container matColumnDef="name" sticky> <ng-container matColumnDef="name" sticky>
<th mat-header-cell *matHeaderCellDef>Name</th> <th mat-header-cell *matHeaderCellDef>Name</th>
<td <td mat-cell *matCellDef="let element">
mat-cell <app-string-cell
*matCellDef="let element" [editable]="element.isGettingEdited"
contenteditable [(value)]="element.name"
(input)="onTableInput(element)" ></app-string-cell>
>
{{ element.name }}
</td> </td>
</ng-container> </ng-container>
@ -58,10 +56,10 @@
<ng-container matColumnDef="frameNumber"> <ng-container matColumnDef="frameNumber">
<th mat-header-cell cdkDrag *matHeaderCellDef>Fahrgestellnummer</th> <th mat-header-cell cdkDrag *matHeaderCellDef>Fahrgestellnummer</th>
<td mat-cell *matCellDef="let element"> <td mat-cell *matCellDef="let element">
<!--<mat-form-field> <app-string-cell
<input matInput color="warn" [value]="element.security.frameNumber"/> [editable]="element.isGettingEdited"
</mat-form-field>--> [(value)]="element.security.frameNumber"
{{ element.security.frameNumber }} ></app-string-cell>
</td> </td>
</ng-container> </ng-container>
@ -69,7 +67,11 @@
<ng-container matColumnDef="numberOfChildren"> <ng-container matColumnDef="numberOfChildren">
<th mat-header-cell cdkDrag *matHeaderCellDef>Anzahl Kinder</th> <th mat-header-cell cdkDrag *matHeaderCellDef>Anzahl Kinder</th>
<td mat-cell *matCellDef="let element"> <td mat-cell *matCellDef="let element">
{{ element.numberOfChildren }} <app-string-cell
[editable]="element.isGettingEdited"
[(value)]="element.numberOfChildren"
inputType="number"
></app-string-cell>
</td> </td>
</ng-container> </ng-container>
@ -78,13 +80,45 @@
<th mat-header-cell *matHeaderCellDef></th> <th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let element"> <td mat-cell *matCellDef="let element">
<div class="button-wrapper"> <div class="button-wrapper">
<button mat-icon-button (click)="edit(element)" [hidden]="isGettingEdited || waitingForEditPermissions"> <button
mat-icon-button
(click)="edit(element)"
*ngIf="
!element.isGettingEdited &&
!element.waitingForEditPermissions &&
!element.locked
"
>
<mat-icon>edit</mat-icon> <mat-icon>edit</mat-icon>
</button> </button>
<mat-spinner [diameter]="32" *ngIf="waitingForEditPermissions"></mat-spinner> <button
<button mat-icon-button> mat-icon-button
*ngIf="
!element.isGettingEdited &&
!element.waitingForEditPermissions &&
!element.locked
"
>
<mat-icon>delete</mat-icon> <mat-icon>delete</mat-icon>
</button> </button>
<mat-spinner
[diameter]="32"
*ngIf="element.waitingForEditPermissions"
></mat-spinner>
<button
mat-icon-button
*ngIf="element.isGettingEdited"
(click)="save(element)"
>
<mat-icon>save</mat-icon>
</button>
<button mat-icon-button *ngIf="element.isGettingEdited">
<mat-icon>cancel</mat-icon>
</button>
<mat-icon *ngIf="element.locked">locked</mat-icon>
</div> </div>
</td> </td>
</ng-container> </ng-container>

@ -1,12 +1,13 @@
import { SelectionModel } from '@angular/cdk/collections'; import { SelectionModel } from '@angular/cdk/collections';
import { Component, ChangeDetectorRef } from '@angular/core'; import { Component } from '@angular/core';
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop'; import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
import { BikesService, CargoBikeResult } from 'src/app/services/bikes.service'; import { BikesService, CargoBikeResult } from 'src/app/services/bikes.service';
import { MatTableDataSource } from '@angular/material/table'; import { deepCopy } from 'src/app/services/deepCopy';
type CargoBikeDataRow = CargoBikeResult & { type CargoBikeDataRow = CargoBikeResult & {
waitingForEditPermissions: boolean; waitingForEditPermissions: boolean;
isGettingEdited: boolean; isGettingEdited: boolean;
locked: boolean;
}; };
@Component({ @Component({
@ -24,36 +25,42 @@ export class BikesComponent {
'buttons', 'buttons',
]; ];
bikes = new MatTableDataSource(<Array<CargoBikeDataRow>>[]); bikes = <Array<any>>[];
selection = new SelectionModel<CargoBikeDataRow>(true, []); selection = new SelectionModel<CargoBikeDataRow>(true, []);
constructor( constructor(private bikesService: BikesService) {
private bikesService: BikesService,
private changeDetectorRefs: ChangeDetectorRef
) {
bikesService.bikes.subscribe((bikes) => { bikesService.bikes.subscribe((bikes) => {
this.bikes = new MatTableDataSource( this.bikes = bikes.map((bike) => {
bikes.map((bike) => { return <any>Object.assign({}, deepCopy(bike), {
return Object.assign({}, bike, {
waitingForEditPermissions: false, waitingForEditPermissions: false,
isGettingEdited: false, isGettingEdited: false,
locked: false,
}); });
}) });
); if (this.bikes.length > 6) {
this.bikes[5].locked = true;
this.bikes[2].locked = true;
}
}); });
bikesService.loadBikes(); bikesService.loadBikes();
} }
edit(row: CargoBikeDataRow) { edit(row: CargoBikeDataRow) {
console.log('isGettingEdited: ' + row.isGettingEdited);
row.waitingForEditPermissions = true; row.waitingForEditPermissions = true;
console.log('edit');
console.log(row.waitingForEditPermissions);
setTimeout(() => { setTimeout(() => {
row.waitingForEditPermissions = false; row.waitingForEditPermissions = false;
row.isGettingEdited = true; row.isGettingEdited = true;
console.log('gets edited'); }, 800);
}, 100); }
save(row: CargoBikeDataRow) {
console.log(row);
}
cancel(row: CargoBikeDataRow) {
//fetch it again
//TODO: remove lock
this.bikesService.reloadBike({id: row.id});
} }
drop(event: CdkDragDrop<string[]>) { drop(event: CdkDragDrop<string[]>) {
@ -67,7 +74,7 @@ export class BikesComponent {
/** Whether the number of selected elements matches the total number of rows. */ /** Whether the number of selected elements matches the total number of rows. */
isAllSelected() { isAllSelected() {
const numSelected = this.selection.selected.length; const numSelected = this.selection.selected.length;
const numRows = this.bikes.data.length; const numRows = this.bikes.length;
return numSelected === numRows; return numSelected === numRows;
} }
@ -75,6 +82,6 @@ export class BikesComponent {
masterToggle() { masterToggle() {
this.isAllSelected() this.isAllSelected()
? this.selection.clear() ? this.selection.clear()
: this.bikes.data.forEach((row) => this.selection.select(row)); : this.bikes.forEach((row) => this.selection.select(row));
} }
} }

@ -1,6 +1,6 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs'; import { BehaviorSubject } from 'rxjs';
import { GetCargoBikesGQL, GetCargoBikesQuery } from 'src/generated/graphql'; import { GetCargoBikesGQL, GetCargoBikesQuery, GetCargoBikeByIdGQL, GetCargoBikeByIdQuery, GetCargoBikeByIdQueryVariables } from 'src/generated/graphql';
import { DeepExtractTypeSkipArrays } from 'ts-deep-extract-types'; import { DeepExtractTypeSkipArrays } from 'ts-deep-extract-types';
export type CargoBikeResult = DeepExtractTypeSkipArrays<GetCargoBikesQuery, ["cargoBikes"]>; export type CargoBikeResult = DeepExtractTypeSkipArrays<GetCargoBikesQuery, ["cargoBikes"]>;
@ -11,11 +11,18 @@ export type CargoBikeResult = DeepExtractTypeSkipArrays<GetCargoBikesQuery, ["ca
export class BikesService { export class BikesService {
bikes: BehaviorSubject<CargoBikeResult[]> = new BehaviorSubject([]); bikes: BehaviorSubject<CargoBikeResult[]> = new BehaviorSubject([]);
constructor(private bikesGQL: GetCargoBikesGQL) { } constructor(private getCargoBikesGQL: GetCargoBikesGQL, private getCargoBikeByIdGQL: GetCargoBikeByIdGQL) { }
loadBikes() { loadBikes() {
this.bikesGQL.watch().valueChanges.subscribe((result) => { this.getCargoBikesGQL.watch().valueChanges.subscribe((result) => {
this.bikes.next(result.data.cargoBikes); this.bikes.next(result.data.cargoBikes);
}); });
} }
reloadBike(parameter: GetCargoBikeByIdQueryVariables) {
this.getCargoBikeByIdGQL.watch().valueChanges.subscribe((result) => {
const newBike = result.data.cargoBikeById;
this.bikes.next(this.bikes.value.map(bike => (newBike.id === bike.id) ? newBike : bike));
});
}
} }

@ -9,7 +9,7 @@
"experimentalDecorators": true, "experimentalDecorators": true,
"moduleResolution": "node", "moduleResolution": "node",
"importHelpers": true, "importHelpers": true,
"target": "es2015", "target": "es2016",
"module": "es2020", "module": "es2020",
"lib": [ "lib": [
"es2018", "es2018",

Loading…
Cancel
Save