Performance optimization WIP

pull/4/head
Max 4 years ago
parent 044e9634e2
commit 56d6272236

@ -1,4 +1,4 @@
import { Component, Input, Output, EventEmitter } from '@angular/core';
import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy } from '@angular/core';
@Component({
selector: 'app-cell',

@ -1,14 +1,14 @@
import { DocumentNode } from 'graphql';
export function isPartOfGraphQLDoc(
variableName: String,
variableName: string,
doc: DocumentNode
): boolean {
return isPartOfSelectionSet(variableName, doc.definitions[0]);
}
function isPartOfSelectionSet(
variableName: String,
variableName: string,
selectionObject: any
): boolean {
const variablePath = variableName.split('.');

@ -17,12 +17,12 @@
<div class="table-container">
<table
mat-table
[dataSource]="data"
class="mat-elevation-z8"
matSort
cdkDropList
cdkDropListOrientation="horizontal"
(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" -->
@ -59,10 +59,12 @@
</th>
<td mat-cell *matCellDef="let element">
<app-cell
[editable]="element.isLockedByMe && !isReadonly(column.name)"
*ngIf="!column.readonly && element.isLockedByMe; else stringValue"
[editable]="true"
[(value)]="element[column.name]"
[inputType]="getType(column.name)"
[inputType]="column.type"
></app-cell>
<ng-template #stringValue>{{ element[column.name] }}</ng-template>
</td>
</ng-container>
@ -100,9 +102,7 @@
<button
mat-icon-button
*ngIf="
element.isLockedByMe && !isLoading(element.id)
"
*ngIf="element.isLockedByMe && !isLoading(element.id)"
(click)="save(element)"
>
<mat-icon>save</mat-icon>
@ -110,9 +110,7 @@
<button
mat-icon-button
matTooltip="Alle ungespeicherten Änderungen verwerfen."
*ngIf="
element.isLockedByMe && !isLoading(element.id)
"
*ngIf="element.isLockedByMe && !isLoading(element.id)"
(click)="cancel(element)"
>
<mat-icon>cancel</mat-icon>

@ -1,5 +1,5 @@
import { SelectionModel } from '@angular/cdk/collections';
import { Component } from '@angular/core';
import { Component, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
import { BikesService, CargoBikeResult } from 'src/app/services/bikes.service';
import { flatten } from 'src/app/helperFunctions/flattenObject';
@ -13,15 +13,23 @@ import {
import { SchemaService } from 'src/app/services/schema.service';
import { logArrayInColumnInfoForm } from 'src/app/helperFunctions/logArrayInColumnInfoForm';
import { MatTableDataSource } from '@angular/material/table';
@Component({
selector: 'app-bikes',
templateUrl: './bikes.component.html',
styleUrls: ['./bikes.component.scss'],
//changeDetection: ChangeDetectionStrategy.OnPush,
})
export class BikesComponent {
/** this array defines the columns and headers of the table and the order they are displayed */
columnInfo = [
columnInfo: {
name: string;
header: string;
sticky?: boolean;
readonly?: boolean;
type?: string;
}[] = [
{ name: 'name', header: 'Name', sticky: true },
{ name: 'id', header: 'ID', readonly: true },
{ name: 'group', header: 'Gruppe' },
@ -90,7 +98,7 @@ export class BikesComponent {
loadingRowIds: string[] = [];
/** data source of the table */
data = [] as Array<any>;
data: MatTableDataSource<any> = new MatTableDataSource() ;
selection = new SelectionModel<CargoBikeResult>(true, []);
reloadingTable = false;
@ -100,41 +108,53 @@ export class BikesComponent {
constructor(
private bikesService: BikesService,
private schemaService: SchemaService
) {
private schemaService: SchemaService,
//private cdr: ChangeDetectorRef
) {}
ngAfterViewInit() {
//this.cdr.detach();
this.addTypesToColumnInfo();
this.addReadOnlyPropertiesToColumnInfo();
this.columnInfo.forEach((column) =>
this.displayedColumns.push(column.name)
);
this.displayedColumns.unshift(this.additionalColumnsFront[0]);
this.displayedColumns.push(this.additionalColumnsBack[0]);
bikesService.loadingRowIds.subscribe((rowIds) => {
this.bikesService.loadingRowIds.subscribe((rowIds) => {
this.loadingRowIds = rowIds;
});
bikesService.bikes.subscribe((newTableDataSource) => {
this.bikesService.bikes.subscribe((newTableDataSource) => {
console.time("newBikes");
this.reloadingTable = false;
const tempDataSource = [];
console.time("overwriteCheck");
for (const row of newTableDataSource) {
const oldRow = this.getRowById(row.id);
/** make sure to not overwrite a row that is being edited */
if (!oldRow) {
tempDataSource.push(flatten(row));
}
else if (!(oldRow.isLockedByMe && row.isLockedByMe)) {
} else if (!(oldRow.isLockedByMe && row.isLockedByMe)) {
tempDataSource.push(flatten(row));
} else if (!!oldRow) {
tempDataSource.push(oldRow);
}
}
this.data = tempDataSource;
console.timeEnd("overwriteCheck");
console.time("assignData");
this.data.data = tempDataSource;
console.timeEnd("assignData");
console.timeEnd("newBikes");
});
bikesService.loadBikes();
}
this.bikesService.loadBikes();
ngOnInit() {
this.relockingInterval = setInterval(() => {
for (const row of this.data) {
for (const row of this.data.data) {
if (row.isLockedByMe) {
this.bikesService.relockBike({ id: row.id });
}
@ -146,6 +166,22 @@ export class BikesComponent {
clearInterval(this.relockingInterval);
}
addTypesToColumnInfo() {
for (const column of this.columnInfo) {
if (!column.type) {
column.type = this.getType(column.name);
}
}
}
addReadOnlyPropertiesToColumnInfo() {
for (const column of this.columnInfo) {
if (!column.readonly) {
column.readonly = this.isReadonly(column.name);
}
}
}
getHeader(propertyName: string) {
return (
this.columnInfo.find((column) => column.name === propertyName)?.header ||
@ -163,8 +199,7 @@ export class BikesComponent {
isReadonly(propertyName: string) {
return (
this.columnInfo.find((column) => column.name === propertyName)
?.readonly ||
this.columnInfo.find((column) => column.name === propertyName).readonly ||
!isPartOfGraphQLDoc(propertyName, CargoBikeFieldsMutableFragmentDoc)
);
}
@ -202,7 +237,7 @@ export class BikesComponent {
}
getRowById(id: string) {
return this.data.find(row => row.id === id);
return this.data.data.find((row) => row.id === id);
}
drop(event: CdkDragDrop<string[]>) {
@ -216,7 +251,7 @@ export class BikesComponent {
/** Whether the number of selected elements matches the total number of rows. */
isAllSelected() {
const numSelected = this.selection.selected.length;
const numRows = this.data.length;
const numRows = this.data.data.length;
return numSelected === numRows;
}
@ -224,6 +259,6 @@ export class BikesComponent {
masterToggle() {
this.isAllSelected()
? this.selection.clear()
: this.data.forEach((row) => this.selection.select(row));
: this.data.data.forEach((row) => this.selection.select(row));
}
}

@ -1,6 +1,7 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { SchemaService } from './schema.service';
import { deepCopy } from 'src/app/helperFunctions/deepCopy';
import {
GetCargoBikesGQL,
GetCargoBikesQuery,
@ -51,7 +52,15 @@ export class BikesService {
loadBikes() {
this.getCargoBikesGQL.fetch().subscribe((result) => {
console.time("addMoreBikes");
for (let i = 1; i <= 500; i++) {
const newBike = deepCopy(result.data.cargoBikes[0]);
newBike.id = (i + 100).toString();
result.data.cargoBikes.push(newBike);
}
console.timeEnd("addMoreBikes");
this.bikes.next(result.data.cargoBikes);
});
}

Loading…
Cancel
Save