WIP timeframes

urls
Max 4 years ago
parent 010025325e
commit 2fc902403e

@ -10,6 +10,7 @@ generates:
- "typescript-apollo-angular"
config:
immutableTypes: false
preResolveTypes: true
src/generated/graphql.schema.json:
plugins:
- "introspection"

@ -9,6 +9,7 @@ import { EquipmentTypesComponent } from './pages/tables/equipment-types/equipmen
import { EquipmentComponent } from './pages/tables/equipment/equipment.component';
import { LendingStationsComponent } from './pages/tables/lending-stations/lending-stations.component';
import { ParticipantsComponent } from './pages/tables/participants/participants.component';
import { TimeFramesComponent } from './pages/tables/time-frames/time-frames.component';
const routes: Routes = [
{ path: 'login', component: LoginComponent },
@ -20,6 +21,7 @@ const routes: Routes = [
{ path: 'table/equipmentTypes', component: EquipmentTypesComponent },
{ path: 'table/engagementTypes', component: EngagementTypesComponent },
{ path: 'table/equipment', component: EquipmentComponent },
{ path: 'table/timeFrames', component: TimeFramesComponent },
{ path: '', redirectTo: 'tableOverview', pathMatch: 'full' },
{ path: 'table', redirectTo: 'tableOverview', pathMatch: 'full' },
{ path: '**', redirectTo: 'tableOverview' },

@ -1,5 +1,5 @@
<div id="page-wrapper">
<mat-toolbar id="navbar">
<mat-toolbar id="navbar" color="primary">
<button mat-icon-button (click)="navService.openNav()" *ngIf="loggedIn">
<mat-icon>menu</mat-icon>
</button>

@ -6,6 +6,8 @@ import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { DragDropModule } from '@angular/cdk/drag-drop';
import { FlexLayoutModule } from '@angular/flex-layout';
import { DatePipe } from '@angular/common'
// Angular Material Components
import { MatToolbarModule } from '@angular/material/toolbar';
import { MatButtonModule } from '@angular/material/button';
@ -28,7 +30,8 @@ import { MatPaginatorModule } from '@angular/material/paginator';
import { MatSortModule } from '@angular/material/sort';
import { MatDialogModule } from '@angular/material/dialog';
import { MatAutocompleteModule } from '@angular/material/autocomplete';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatNativeDateModule, MAT_DATE_LOCALE } from '@angular/material/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
@ -45,14 +48,19 @@ import {SidenavProfileComponent} from './components/sidenav-profile/sidenav-prof
import { NavService } from './components/menu-list-item/nav.service';
import { TokenInterceptor } from './helper/token.interceptor';
import { BikeComponent } from './pages/dataPages/bike/bike.component';
import { TableComponent, DeleteConfirmationDialog } from './components/table/table.component';
import {
TableComponent,
DeleteConfirmationDialog,
} from './components/table/table.component';
import { DataPageComponent } from './components/data-page/data-page.component';
import { EquipmentTypesComponent } from './pages/tables/equipment-types/equipment-types.component';
import { EngagementTypesComponent } from './pages/tables/engagement-types/engagement-types.component';
import { WorkshopsComponent } from './pages/tables/workshops/workshops.component';
import { ReferenceTableComponent } from './components/reference-table/reference-table.component'
import { ReferenceTableComponent } from './components/reference-table/reference-table.component';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { EquipmentComponent } from './pages/tables/equipment/equipment.component';
import { TimeFramesComponent } from './pages/tables/time-frames/time-frames.component';
@NgModule({
@ -74,7 +82,8 @@ import { EquipmentComponent } from './pages/tables/equipment/equipment.component
EngagementTypesComponent,
WorkshopsComponent,
ReferenceTableComponent,
EquipmentComponent
EquipmentComponent,
TimeFramesComponent,
],
imports: [
BrowserModule,
@ -107,12 +116,19 @@ import { EquipmentComponent } from './pages/tables/equipment/equipment.component
MatPaginatorModule,
MatSortModule,
MatDialogModule,
MatAutocompleteModule
MatAutocompleteModule,
MatDatepickerModule,
MatNativeDateModule
],
providers: [
NavService,
MatNativeDateModule,
MatDatepickerModule,
DatePipe,
{ provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true },
{provide: MAT_DATE_LOCALE, useValue: 'de-DE'},
],
providers: [NavService,
{ provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true }],
bootstrap: [AppComponent],
})
export class AppModule {
}
export class AppModule {}

@ -49,7 +49,7 @@ export class ReferenceTableComponent {
@Input()
set data(newdata) {
if (!newdata) return;
if (!newdata) { return; }
this.dataSource.data = [];
for (const element of newdata) {
this.dataSource.data.push(flatten(element));
@ -145,7 +145,7 @@ export class ReferenceTableComponent {
const index = this.dataSource.data.findIndex(
(element) => element.id === row.id
);
if (index === -1) return;
if (index === -1) { return; }
this.dataSource.data.splice(index, 1);
this.dataSource.data = this.dataSource.data; //needed to trigger update lol
this.filterPossibleValueOptions();

@ -118,6 +118,7 @@
<td mat-cell *matCellDef="let element">
<app-cell
*ngIf="
column.type === 'DateRange' ||
column.type === 'Boolean' ||
element.newObject ||
(!column.readonly && element.isLockedByMe);

@ -9,7 +9,6 @@ import {
ChangeDetectorRef,
} from '@angular/core';
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
import { CargoBikeResult } from 'src/app/services/bikes.service';
import { flatten } from 'src/app/helperFunctions/flattenObject';
import { deepen } from 'src/app/helperFunctions/deepenObject';
import { SchemaService } from 'src/app/services/schema.service';
@ -64,7 +63,7 @@ export class TableComponent implements AfterViewInit {
/** data source of the table */
data: MatTableDataSource<any> = new MatTableDataSource();
selection = new SelectionModel<CargoBikeResult>(true, []);
selection = new SelectionModel<any>(true, []);
reloadingTable = false;
@ -194,7 +193,7 @@ export class TableComponent implements AfterViewInit {
this.tableDataGQLUpdateInputType,
column.dataPath
);
column.readonly = column.readonly || !typeInformation.isPartOfType;
column.readonly = column.readonly !== null ? column.readonly : !typeInformation.isPartOfType;
}
for (const column of this.columnInfo) {
const typeInformation = this.schemaService.getTypeInformation(

@ -6,7 +6,8 @@
[disabled]="!editable"
[ngModel]="value"
(ngModelChange)="change($event)"
><span *ngIf="label">{{label}}</span></mat-checkbox>
><span *ngIf="label">{{ label }}</span></mat-checkbox
>
</div>
<div #enumInputType *ngIf="htmlInputType === 'enum'">
@ -29,6 +30,56 @@
</ng-template>
</div>
<ng-container *ngIf="htmlInputType === 'dateRange'">
<mat-form-field>
<mat-label>Zeitraum auswählen</mat-label>
<mat-date-range-input [rangePicker]="picker" disabled>
<input
matStartDate
placeholder="Startdatum"
[value]="value?.from"
(dateChange)="startDateChange($event)"
/>
<input
matEndDate
placeholder="Enddatum"
[value]="value?.to"
(dateChange)="endDateChange($event)"
/>
</mat-date-range-input>
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-date-range-picker
#picker
[disabled]="!editable"
></mat-date-range-picker>
</mat-form-field>
</ng-container>
<div *ngIf="htmlInputType === 'numberRange'" class="number-range-wrapper">
<mat-form-field class="number-range-form-field">
<mat-label *ngIf="label">{{ label }}</mat-label>
<input
matInput
type="number"
[disabled]="!editable"
[value]="value.min"
(input)="minValueChange($event)"
[required]="required"
/>
</mat-form-field>
<span class="range-spacer">-</span>
<mat-form-field class="number-range-form-field">
<input
matInput
type="number"
[disabled]="!editable"
[value]="value.max"
(input)="maxValueChange($event)"
[required]="required"
/>
</mat-form-field>
</div>
<div
#otherInputType
*ngIf="htmlInputType === 'number' || htmlInputType === 'text'"
@ -47,6 +98,8 @@
</mat-form-field>
<ng-template #nonEditableText>
<span *ngIf="!link">{{ value }}</span>
<a mat-button color="primary" *ngIf="link" [routerLink]="link">{{value}}</a>
<a mat-button color="primary" *ngIf="link" [routerLink]="link">{{
value
}}</a>
</ng-template>
</div>

@ -0,0 +1,8 @@
.number-range-wrapper {
display: flex;
flex-direction: row;
align-items: center;
.range-spacer {
margin: 0 0.5em;
}
}

@ -1,3 +1,4 @@
import { DatePipe } from '@angular/common';
import {
Component,
Input,
@ -6,6 +7,7 @@ import {
ChangeDetectionStrategy,
ViewChild,
ChangeDetectorRef,
AfterViewInit,
} from '@angular/core';
@Component({
@ -13,10 +15,15 @@ import {
templateUrl: './cell.component.html',
styleUrls: ['./cell.component.scss'],
})
export class CellComponent {
export class CellComponent implements AfterViewInit {
@Input()
value: number | string | boolean;
@Output() valueChange = new EventEmitter<number | string | boolean>();
value: any; // number | string | boolean | { start: string; end: string; };
minValue: number;
maxValue: number;
@Output() valueChange = new EventEmitter<
number | string | boolean | { start: string; end: string }
>();
@Input()
editable = false;
_inputType = 'text';
@ -29,23 +36,23 @@ export class CellComponent {
this.getHtmlInputType(type);
}
@Input()
required: boolean = false;
required = false;
@Input()
link: string = null;
@Input()
label: string = null;
@Output() validityChange = new EventEmitter<boolean>();
isValid: boolean = true;
isValid = true;
enumValues = [];
htmlInputType: string = 'string';
htmlInputType = 'string';
@ViewChild('input') input: any;
constructor(private cdr: ChangeDetectorRef) {}
constructor(private cdr: ChangeDetectorRef, public datepipe: DatePipe) {}
ngAfterViewInit() {
ngAfterViewInit(): void {
if (this.required) {
this.input?.control?.markAsTouched();
this.checkIfValid();
@ -63,7 +70,7 @@ export class CellComponent {
}
}
getHtmlInputType(type: string) {
getHtmlInputType(type: string): void {
if (type.split('//')[0] === 'Enum') {
this.enumValues = type.split('//').slice(1);
this.htmlInputType = 'enum';
@ -73,10 +80,23 @@ export class CellComponent {
this.htmlInputType = 'text';
} else if (type === 'Boolean') {
this.htmlInputType = 'boolean';
} else if (type === 'Date') {
this.htmlInputType = 'date';
} else if (type === 'DateRange') {
this.htmlInputType = 'dateRange';
} else if (type === 'NumRange') {
this.htmlInputType = 'numberRange';
if (
!this.value ||
this.value.min === undefined ||
this.value.max === undefined
) {
this.value = { min: null, max: null };
}
}
}
change(newValue) {
change(newValue): void {
if (this.inputType === 'Int') {
newValue = newValue.toString().replace('.', '');
}
@ -88,10 +108,50 @@ export class CellComponent {
this.checkIfValid();
}
startDateChange(event): void {
console.log('start');
console.log(event.value);
console.log(this.transformDate(event.value));
this.value.start = this.transformDate(event.value);
this.valueChange.emit(this.value);
}
endDateChange(event) {
console.log('end');
console.log(event.value);
console.log(this.transformDate(event.value));
this.value.end = this.transformDate(event.value);
this.valueChange.emit(this.value);
}
minValueChange(event) {
this.value.min = this.toNumber(event.target.value);
this.valueChange.emit(this.value);
console.log(this.value);
}
maxValueChange(event) {
this.value.max = this.toNumber(event.target.value);
this.valueChange.emit(this.value);
console.log(this.value);
}
transformDate(date) {
return this.datepipe.transform(date, 'yyyy-MM-dd');
}
checkIfValid() {
if (this.required && this.inputType !== 'Boolean') {
this.isValid = this.input?.control?.valid || false;
this.validityChange.emit(this.isValid);
}
}
toNumber(str: string): number {
if (str === '') {
return null;
}
return +str;
}
}

@ -33,12 +33,18 @@ fragment CargoBikeFieldsForTable on CargoBike {
bikeLength
bikeWeight
bikeWidth
minBoxHeight
maxBoxHeight
minBoxLength
maxBoxLength
minBoxWidth
maxBoxWidth
boxHeightRange {
max
min
}
boxLengthRange {
min
max
}
boxWidthRange {
min
max
}
hasCoverBox
lockable
maxWeightBox

@ -1,7 +1,9 @@
fragment TimeFrameFieldsForBikePage on TimeFrame {
id
dateRange {
from
to
}
note
lendingStation {
...LendingStationFieldsForBikePage
@ -11,3 +13,24 @@ fragment TimeFrameFieldsForBikePage on TimeFrame {
lockedBy
lockedUntil
}
fragment TimeFrameFields on TimeFrame {
id
dateRange {
from
to
}
note
lendingStation {
id
name
}
cargoBike {
id
name
}
isLocked
isLockedByMe
lockedBy
lockedUntil
}

@ -0,0 +1,33 @@
query GetTimeFrames {
timeFrames {
...TimeFrameFields
}
}
mutation CreateTimeFrame($timeFrame: TimeFrameCreateInput!) {
createTimeFrame(timeFrame: $timeFrame) {
...TimeFrameFields
}
}
mutation UpdateTimeFrame($timeFrame: TimeFrameUpdateInput!) {
updateTimeFrame(timeFrame: $timeFrame) {
...TimeFrameFields
}
}
mutation LockTimeFrame($id: ID!) {
lockTimeFrame(id: $id) {
...TimeFrameFields
}
}
mutation UnlockTimeFrame($id: ID!) {
unlockTimeFrame(id: $id) {
...TimeFrameFields
}
}
mutation DeleteTimeFrame($id: ID!) {
deleteTimeFrame(id: $id)
}

@ -67,28 +67,16 @@ export class BikeComponent implements OnInit {
{ dataPath: 'dimensionsAndLoad.bikeHeight', translation: 'Höhe' },
{ dataPath: 'dimensionsAndLoad.bikeWidth', translation: 'Breite' },
{
dataPath: 'dimensionsAndLoad.minBoxHeight',
translation: 'Boxhöhe min',
dataPath: 'dimensionsAndLoad.boxHeightRange',
translation: 'Boxhöhe',
},
{
dataPath: 'dimensionsAndLoad.maxBoxHeight',
translation: 'Boxhöhe max',
dataPath: 'dimensionsAndLoad.boxLengthRange',
translation: 'Boxlänge',
},
{
dataPath: 'dimensionsAndLoad.minBoxLength',
translation: 'Boxlänge min',
},
{
dataPath: 'dimensionsAndLoad.maxBoxLength',
translation: 'Boxlänge max',
},
{
dataPath: 'dimensionsAndLoad.minBoxWidth',
translation: 'Boxbreite min',
},
{
dataPath: 'dimensionsAndLoad.maxBoxWidth',
translation: 'Boxbreite max',
dataPath: 'dimensionsAndLoad.boxWidthRange',
translation: 'Boxbreite',
},
{
dataPath: 'dimensionsAndLoad.hasCoverBox',

@ -49,12 +49,9 @@ export class BikesComponent implements OnInit {
{ dataPath: 'dimensionsAndLoad.bikeWeight', translation: 'Gewicht' },
{ dataPath: 'dimensionsAndLoad.bikeHeight', translation: 'Höhe' },
{ dataPath: 'dimensionsAndLoad.bikeWidth', translation: 'Breite' },
{ dataPath: 'dimensionsAndLoad.minBoxHeight', translation: 'Boxhöhe min' },
{ dataPath: 'dimensionsAndLoad.maxBoxHeight', translation: 'Boxhöhe max' },
{ dataPath: 'dimensionsAndLoad.minBoxLength', translation: 'Boxlänge min' },
{ dataPath: 'dimensionsAndLoad.maxBoxLength', translation: 'Boxlänge max' },
{ dataPath: 'dimensionsAndLoad.minBoxWidth', translation: 'Boxbreite min' },
{ dataPath: 'dimensionsAndLoad.maxBoxWidth', translation: 'Boxbreite max' },
{ dataPath: 'dimensionsAndLoad.boxHeightRange', translation: 'Boxhöhe' },
{ dataPath: 'dimensionsAndLoad.boxLengthRange', translation: 'Boxlänge' },
{ dataPath: 'dimensionsAndLoad.boxWidthRange', translation: 'Boxbreite' },
{
dataPath: 'dimensionsAndLoad.hasCoverBox',
translation: 'Boxabdeckung j/n',

@ -0,0 +1,13 @@
<app-table
[headline]="headline"
[columnInfo]="columnInfo"
[dataService]="dataService"
[tableDataGQLType]="tableDataGQLType"
[tableDataGQLCreateInputType]="tableDataGQLCreateInputType"
[tableDataGQLUpdateInputType]="tableDataGQLUpdateInputType"
(createEvent)="create($event)"
(lockEvent)="lock($event)"
(saveEvent)="save($event)"
(cancelEvent)="cancel($event)"
(deleteEvent)="delete($event)"
></app-table>

@ -0,0 +1,61 @@
import { Component, OnInit } from '@angular/core';
import { TimeFrameService } from 'src/app/services/timeFrame.service';
@Component({
selector: 'app-time-frames',
templateUrl: './time-frames.component.html',
styleUrls: ['./time-frames.component.scss'],
})
export class TimeFramesComponent implements OnInit {
headline = 'Zeitscheiben';
columnInfo = [
{ dataPath: 'dataRange', translation: 'Zeitraum', type: 'DateRange', readonly: false },
{
dataPath: 'cargoBike.name',
translation: 'Lastenrad',
link: (element) => {
return '/bike/' + element['cargoBike.id'];
},
},
{
dataPath: 'lendingStation.name',
translation: 'Ausleihstation',
link: (element) => {
return '/lendingStation/' + element['lendingStation.id'];
},
},
];
dataService: TimeFrameService;
tableDataGQLType: string = 'TimeFrame';
tableDataGQLCreateInputType: string = 'TimeFrameCreateInput';
tableDataGQLUpdateInputType: string = 'TimeFrameUpdateInput';
loadingRowIds: string[] = [];
constructor(private service: TimeFrameService) {}
ngOnInit() {
this.dataService = this.service;
}
create(value: { currentId: string; row: any }) {
this.dataService.create(value.currentId, { timeFrame: value.row });
}
lock(row: any) {
this.dataService.lock({ id: row.id });
}
save(row: any) {
this.dataService.update({ timeFrame: row });
}
cancel(row: any) {
this.dataService.unlock({ id: row.id });
}
delete(row: any) {
this.dataService.delete({ id: row.id });
}
}

@ -2,7 +2,6 @@ import { Injectable } from '@angular/core';
import { BehaviorSubject, Subject } from 'rxjs';
import {
GetCargoBikesGQL,
GetCargoBikesQuery,
ReloadCargoBikeByIdGQL,
ReloadCargoBikeByIdQueryVariables,
UpdateCargoBikeGQL,
@ -18,19 +17,13 @@ import {
GetCargoBikeByIdGQL,
GetCargoBikeByIdQueryVariables,
} from 'src/generated/graphql';
import { DeepExtractTypeSkipArrays } from 'ts-deep-extract-types';
export type CargoBikeResult = DeepExtractTypeSkipArrays<
GetCargoBikesQuery,
['cargoBikes']
>;
@Injectable({
providedIn: 'root',
})
export class BikesService {
/** CargoBikes Array */
tableData: BehaviorSubject<CargoBikeResult[]> = new BehaviorSubject(null);
tableData: BehaviorSubject<any[]> = new BehaviorSubject(null);
loadingRowIds: BehaviorSubject<string[]> = new BehaviorSubject([]);
successfullyCreatedRowWithId: Subject<string> = new Subject();
pageData: BehaviorSubject<any> = new BehaviorSubject(null);
@ -141,7 +134,7 @@ export class BikesService {
this.deleteCargoBikeGQL
.mutate(variables)
.subscribe((result) => {
if (result.data.deleteCargoBike) {
if (result.data) {
this.tableData.next(
[...this.tableData.value].filter((bike) => bike.id !== variables.id)
);

@ -103,7 +103,7 @@ export class EquipmentService {
this.deleteEquipmentGQL
.mutate(variables)
.subscribe((result) => {
if (result.data.deleteEquipment) {
if (result.data) {
this.tableData.next(
[...this.tableData.value].filter((bike) => bike.id !== variables.id)
);

@ -103,7 +103,7 @@ export class EquipmentTypeService {
this.deleteEquipmentTypeGQL
.mutate(variables)
.subscribe((result) => {
if (result.data.deleteEquipmentType) {
if (result.data) {
this.tableData.next(
[...this.tableData.value].filter((bike) => bike.id !== variables.id)
);

@ -0,0 +1,125 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject, Subject } from 'rxjs';
import {
GetTimeFramesGQL,
CreateTimeFrameGQL,
CreateTimeFrameMutationVariables,
UpdateTimeFrameGQL,
UpdateTimeFrameMutationVariables,
LockTimeFrameGQL,
LockTimeFrameMutationVariables,
UnlockTimeFrameGQL,
UnlockTimeFrameMutationVariables,
DeleteTimeFrameGQL,
DeleteTimeFrameMutationVariables,
} from '../../generated/graphql';
@Injectable({
providedIn: 'root',
})
export class TimeFrameService {
/** TimeFrames Array */
tableData: BehaviorSubject<any[]> = new BehaviorSubject(null);
loadingRowIds: BehaviorSubject<string[]> = new BehaviorSubject([]);
successfullyCreatedRowWithId: Subject<string> = new Subject();
//pageData: BehaviorSubject<any> = new BehaviorSubject([]);
//isLoadingPageData: BehaviorSubject<boolean> = new BehaviorSubject(false);
constructor(
private getTimeFramesGQL: GetTimeFramesGQL,
private createTimeFrameGQL: CreateTimeFrameGQL,
private updateTimeFrameGQL: UpdateTimeFrameGQL,
private lockTimeFrameGQL: LockTimeFrameGQL,
private unlockTimeFrameGQL: UnlockTimeFrameGQL,
private deleteTimeFrameGQL: DeleteTimeFrameGQL
) {}
addLoadingRowId(id: string) {
this.loadingRowIds.next([...this.loadingRowIds.value, id]);
}
removeLoadingRowId(id: string) {
this.loadingRowIds.value.forEach((item, index) => {
if (item === id) {
this.loadingRowIds.value.splice(index, 1);
}
});
this.loadingRowIds.next(this.loadingRowIds.value);
}
loadTableData() {
this.tableData.next(null);
this.getTimeFramesGQL.fetch().subscribe((result) => {
this.tableData.next(result.data.timeFrames);
});
}
create(currentId: string, variables: CreateTimeFrameMutationVariables) {
this.createTimeFrameGQL.mutate(variables).subscribe((result) => {
const newRow = result.data.createTimeFrame;
this.tableData.next([newRow, ...this.tableData.value]);
this.successfullyCreatedRowWithId.next(currentId);
});
}
update(variables: UpdateTimeFrameMutationVariables) {
this.addLoadingRowId(variables.timeFrame.id);
this.updateTimeFrameGQL
.mutate(variables)
.subscribe((result) => {
this.updateDataRowFromResponse(result.data.updateTimeFrame);
})
.add(() => {
this.removeLoadingRowId(variables.timeFrame.id);
});
}
lock(variables: LockTimeFrameMutationVariables) {
this.addLoadingRowId(variables.id);
this.lockTimeFrameGQL
.mutate(variables)
.subscribe((result) => {
this.updateDataRowFromResponse(result.data.lockTimeFrame);
})
.add(() => {
this.removeLoadingRowId(variables.id);
});
}
unlock(variables: UnlockTimeFrameMutationVariables) {
this.addLoadingRowId(variables.id);
this.unlockTimeFrameGQL
.mutate(variables)
.subscribe((result) => {
this.updateDataRowFromResponse(result.data.unlockTimeFrame);
})
.add(() => {
this.removeLoadingRowId(variables.id);
});
}
delete(variables: DeleteTimeFrameMutationVariables) {
this.addLoadingRowId(variables.id);
this.deleteTimeFrameGQL
.mutate(variables)
.subscribe((result) => {
if (result.data) {
this.tableData.next(
[...this.tableData.value].filter((bike) => bike.id !== variables.id)
);
}
})
.add(() => {
this.removeLoadingRowId(variables.id);
});
}
private updateDataRowFromResponse(rowFromResponse: any) {
if (this.tableData.value) {
const newTableData = this.tableData.value.map((row) =>
rowFromResponse.id === row.id ? rowFromResponse : row
);
this.tableData.next(newTableData);
}
}
}

@ -1,6 +1,5 @@
{
"__schema": {
"description": null,
"queryType": {
"name": "Query"
},
@ -77,9 +76,25 @@
"description": null,
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "state",
"description": null,
"args": [],
"type": {
"kind": "ENUM",
"name": "BikeState",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
@ -181,13 +196,9 @@
"description": "Does not refer to an extra table in the database.",
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "DimensionsAndLoad",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
@ -339,13 +350,9 @@
"description": null,
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "InsuranceData",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
@ -545,6 +552,35 @@
"enumValues": null,
"possibleTypes": null
},
{
"kind": "ENUM",
"name": "BikeState",
"description": "Status of the CargoBike. More fields will be added, or removed.",
"fields": null,
"inputFields": null,
"interfaces": null,
"enumValues": [
{
"name": "ACTIVE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "INACTIVE",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "INPREPARATION",
"description": null,
"isDeprecated": false,
"deprecationReason": null
}
],
"possibleTypes": null
},
{
"kind": "INPUT_OBJECT",
"name": "CargoBikeCreateInput",
@ -579,6 +615,16 @@
},
"defaultValue": null
},
{
"name": "state",
"description": null,
"type": {
"kind": "ENUM",
"name": "BikeState",
"ofType": null
},
"defaultValue": null
},
{
"name": "modelName",
"description": null,
@ -667,13 +713,9 @@
"name": "technicalEquipment",
"description": "Does not refer to an extra table in the database.",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "INPUT_OBJECT",
"name": "TechnicalEquipmentCreateInput",
"ofType": null
}
},
"defaultValue": null
},
@ -681,13 +723,9 @@
"name": "dimensionsAndLoad",
"description": "Does not refer to an extra table in the database.",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "INPUT_OBJECT",
"name": "DimensionsAndLoadCreateInput",
"ofType": null
}
},
"defaultValue": null
},
@ -753,13 +791,9 @@
"name": "insuranceData",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "INPUT_OBJECT",
"name": "InsuranceDataCreateInput",
"ofType": null
}
},
"defaultValue": null
},
@ -767,13 +801,9 @@
"name": "taxes",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "INPUT_OBJECT",
"name": "TaxesCreateInput",
"ofType": null
}
},
"defaultValue": null
}
@ -822,6 +852,16 @@
},
"defaultValue": null
},
{
"name": "state",
"description": null,
"type": {
"kind": "ENUM",
"name": "BikeState",
"ofType": null
},
"defaultValue": null
},
{
"name": "modelName",
"description": null,
@ -1005,13 +1045,9 @@
"description": "Eventually, this field will become an enum or a separate data table and user can choose from a pool of insurance companies.",
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
@ -1021,13 +1057,9 @@
"description": null,
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
@ -1037,13 +1069,9 @@
"description": null,
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
@ -1053,13 +1081,9 @@
"description": null,
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
@ -1069,13 +1093,9 @@
"description": "eg. Anbieter, flotte, eigenleistung",
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
@ -1085,13 +1105,9 @@
"description": null,
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
@ -1113,13 +1129,9 @@
"description": null,
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
@ -1186,13 +1198,9 @@
"name": "name",
"description": "Eventually, this field will become an enum or a separate data table and user can choose from a pool of insurance companies.",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"defaultValue": null
},
@ -1200,13 +1208,9 @@
"name": "benefactor",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"defaultValue": null
},
@ -1214,13 +1218,9 @@
"name": "billing",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"defaultValue": null
},
@ -1228,13 +1228,9 @@
"name": "noPnP",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"defaultValue": null
},
@ -1242,13 +1238,9 @@
"name": "maintenanceResponsible",
"description": "eg. Anbieter, flotte, eigenleistung",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"defaultValue": null
},
@ -1256,13 +1248,9 @@
"name": "maintenanceBenefactor",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"defaultValue": null
},
@ -1280,13 +1268,9 @@
"name": "hasFixedRate",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
}
},
"defaultValue": null
},
@ -1448,108 +1432,130 @@
},
{
"kind": "OBJECT",
"name": "DimensionsAndLoad",
"description": "How are the dimensions and how much weight can handle a bike. This data is merged in the CargoBike table and the BikeModel table.",
"name": "NumRange",
"description": null,
"fields": [
{
"name": "hasCoverBox",
"name": "min",
"description": null,
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Boolean",
"name": "Float",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "lockable",
"description": "cover box can be locked",
"name": "max",
"description": null,
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Boolean",
"name": "Float",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [],
"enumValues": null,
"possibleTypes": null
},
{
"name": "minBoxLength",
"kind": "INPUT_OBJECT",
"name": "NumRangeInput",
"description": "If min or max is omitted, the omitted value will be the same as the other given value\nSo if you pass one as null, both values with be over written with null.",
"fields": null,
"inputFields": [
{
"name": "min",
"description": null,
"args": [],
"type": {
"kind": "SCALAR",
"name": "Float",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
"defaultValue": null
},
{
"name": "maxBoxLength",
"name": "max",
"description": null,
"args": [],
"type": {
"kind": "SCALAR",
"name": "Float",
"ofType": null
},
"defaultValue": null
}
],
"interfaces": null,
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "DimensionsAndLoad",
"description": "How are the dimensions and how much weight can handle a bike. This data is merged in the CargoBike table and the BikeModel table.",
"fields": [
{
"name": "hasCoverBox",
"description": null,
"args": [],
"type": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "minBoxWidth",
"description": null,
"name": "lockable",
"description": "cover box can be locked",
"args": [],
"type": {
"kind": "SCALAR",
"name": "Float",
"name": "Boolean",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "maxBoxWidth",
"name": "boxLengthRange",
"description": null,
"args": [],
"type": {
"kind": "SCALAR",
"name": "Float",
"kind": "OBJECT",
"name": "NumRange",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "minBoxHeight",
"name": "boxWidthRange",
"description": null,
"args": [],
"type": {
"kind": "SCALAR",
"name": "Float",
"kind": "OBJECT",
"name": "NumRange",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "maxBoxHeight",
"name": "boxHeightRange",
"description": null,
"args": [],
"type": {
"kind": "SCALAR",
"name": "Float",
"kind": "OBJECT",
"name": "NumRange",
"ofType": null
},
"isDeprecated": false,
@ -1655,13 +1661,9 @@
"name": "hasCoverBox",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
}
},
"defaultValue": null
},
@ -1669,72 +1671,38 @@
"name": "lockable",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
}
},
"defaultValue": null
},
{
"name": "minBoxLength",
"description": null,
"type": {
"kind": "SCALAR",
"name": "Float",
"ofType": null
},
"defaultValue": null
},
{
"name": "maxBoxLength",
"name": "boxLengthRange",
"description": null,
"type": {
"kind": "SCALAR",
"name": "Float",
"ofType": null
},
"defaultValue": null
},
{
"name": "minBoxWidth",
"description": null,
"type": {
"kind": "SCALAR",
"name": "Float",
"ofType": null
},
"defaultValue": null
},
{
"name": "maxBoxWidth",
"description": null,
"type": {
"kind": "SCALAR",
"name": "Float",
"kind": "INPUT_OBJECT",
"name": "NumRangeInput",
"ofType": null
},
"defaultValue": null
},
{
"name": "minBoxHeight",
"name": "boxWidthRange",
"description": null,
"type": {
"kind": "SCALAR",
"name": "Float",
"kind": "INPUT_OBJECT",
"name": "NumRangeInput",
"ofType": null
},
"defaultValue": null
},
{
"name": "maxBoxHeight",
"name": "boxHeightRange",
"description": null,
"type": {
"kind": "SCALAR",
"name": "Float",
"kind": "INPUT_OBJECT",
"name": "NumRangeInput",
"ofType": null
},
"defaultValue": null
@ -1841,61 +1809,31 @@
"defaultValue": null
},
{
"name": "minBoxLength",
"description": null,
"type": {
"kind": "SCALAR",
"name": "Float",
"ofType": null
},
"defaultValue": null
},
{
"name": "maxBoxLength",
"name": "boxLengthRange",
"description": null,
"type": {
"kind": "SCALAR",
"name": "Float",
"ofType": null
},
"defaultValue": null
},
{
"name": "minBoxWidth",
"description": null,
"type": {
"kind": "SCALAR",
"name": "Float",
"ofType": null
},
"defaultValue": null
},
{
"name": "maxBoxWidth",
"description": null,
"type": {
"kind": "SCALAR",
"name": "Float",
"kind": "INPUT_OBJECT",
"name": "NumRangeInput",
"ofType": null
},
"defaultValue": null
},
{
"name": "minBoxHeight",
"name": "boxWidthRange",
"description": null,
"type": {
"kind": "SCALAR",
"name": "Float",
"kind": "INPUT_OBJECT",
"name": "NumRangeInput",
"ofType": null
},
"defaultValue": null
},
{
"name": "maxBoxHeight",
"name": "boxHeightRange",
"description": null,
"type": {
"kind": "SCALAR",
"name": "Float",
"kind": "INPUT_OBJECT",
"name": "NumRangeInput",
"ofType": null
},
"defaultValue": null
@ -1985,13 +1923,9 @@
"description": null,
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
@ -2001,13 +1935,9 @@
"description": null,
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
@ -2017,13 +1947,9 @@
"description": null,
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
@ -2056,13 +1982,9 @@
"name": "bicycleShift",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"defaultValue": null
},
@ -2070,13 +1992,9 @@
"name": "isEBike",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
}
},
"defaultValue": null
},
@ -2084,13 +2002,9 @@
"name": "hasLightSystem",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
}
},
"defaultValue": null
},
@ -4040,13 +3954,9 @@
"description": null,
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
@ -4079,13 +3989,9 @@
"name": "costCenter",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"defaultValue": null
},
@ -4639,7 +4545,7 @@
{
"kind": "OBJECT",
"name": "BikeEvent",
"description": "An Event is a point in time, when the state of the bike somehow changed.",
"description": "An Event is a point in time concerning one cargo bike of an event type. For example a chain swap.",
"fields": [
{
"name": "id",
@ -6928,11 +6834,11 @@
},
{
"kind": "OBJECT",
"name": "TimeFrame",
"description": "(dt. Zeitscheibe) When was a bike where",
"name": "DateRange",
"description": null,
"fields": [
{
"name": "id",
"name": "from",
"description": null,
"args": [],
"type": {
@ -6940,17 +6846,40 @@
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"name": "Date",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "to",
"description": "will be infinity of not omitted",
"args": [],
"type": {
"kind": "SCALAR",
"name": "Date",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [],
"enumValues": null,
"possibleTypes": null
},
{
"kind": "INPUT_OBJECT",
"name": "DateRangeInput",
"description": null,
"fields": null,
"inputFields": [
{
"name": "from",
"description": "format YYYY-MM-dd",
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
@ -6960,18 +6889,57 @@
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
"defaultValue": null
},
{
"name": "to",
"description": "format YYYY-MM-dd",
"args": [],
"description": "format YYYY-MM-dd\nwill be infinity of not omitted",
"type": {
"kind": "SCALAR",
"name": "Date",
"ofType": null
},
"defaultValue": null
}
],
"interfaces": null,
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "TimeFrame",
"description": "(dt. Zeitscheibe) When was a bike where",
"fields": [
{
"name": "id",
"description": null,
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "dateRange",
"description": null,
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "DateRange",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
@ -7088,29 +7056,19 @@
"fields": null,
"inputFields": [
{
"name": "from",
"name": "dateRange",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Date",
"kind": "INPUT_OBJECT",
"name": "DateRangeInput",
"ofType": null
}
},
"defaultValue": null
},
{
"name": "to",
"description": null,
"type": {
"kind": "SCALAR",
"name": "Date",
"ofType": null
},
"defaultValue": null
},
{
"name": "note",
"description": null,
@ -7175,21 +7133,11 @@
"defaultValue": null
},
{
"name": "from",
"description": null,
"type": {
"kind": "SCALAR",
"name": "Date",
"ofType": null
},
"defaultValue": null
},
{
"name": "to",
"name": "dateRange",
"description": null,
"type": {
"kind": "SCALAR",
"name": "Date",
"kind": "INPUT_OBJECT",
"name": "DateRangeInput",
"ofType": null
},
"defaultValue": null

File diff suppressed because it is too large Load Diff

11017
yarn.lock

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save