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';
@ -20,15 +22,16 @@ import { MatFormFieldModule } from '@angular/material/form-field';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { MatCheckboxModule } from '@angular/material/checkbox';
import {MatCardModule} from '@angular/material/card';
import {MatGridListModule} from '@angular/material/grid-list';
import {MatTooltipModule} from '@angular/material/tooltip';
import {MatSelectModule} from '@angular/material/select';
import { MatCardModule } from '@angular/material/card';
import { MatGridListModule } from '@angular/material/grid-list';
import { MatTooltipModule } from '@angular/material/tooltip';
import { MatSelectModule } from '@angular/material/select';
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 { 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';
@ -41,18 +44,23 @@ import { LendingStationsComponent } from './pages/tables/lending-stations/lendin
import { TableOverviewComponent } from './pages/table-overview/table-overview.component';
import { CellComponent } from './components/tableComponents/cell/cell.component';
import { MenuListItemComponent } from './components/menu-list-item/menu-list-item.component';
import {SidenavProfileComponent} from './components/sidenav-profile/sidenav-profile.component';
import { NavService }from './components/menu-list-item/nav.service';
import { SidenavProfileComponent } from './components/sidenav-profile/sidenav-profile.component';
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,
{ provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true }],
providers: [
NavService,
MatNativeDateModule,
MatDatepickerModule,
DatePipe,
{ provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true },
{provide: MAT_DATE_LOCALE, useValue: 'de-DE'},
],
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,12 +6,13 @@
[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'">
<mat-form-field *ngIf="editable || label; else nonEditableText">
<mat-label *ngIf="label">{{label}}</mat-label>
<mat-label *ngIf="label">{{ label }}</mat-label>
<mat-select
[(ngModel)]="value"
(ngModelChange)="change($event)"
@ -29,12 +30,62 @@
</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'"
>
<mat-form-field *ngIf="editable || label; else nonEditableText">
<mat-label *ngIf="label">{{label}}</mat-label>
<mat-label *ngIf="label">{{ label }}</mat-label>
<input
#input="ngModel"
matInput
@ -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
@ -77,23 +83,23 @@ fragment CargoBikeFieldsForTable on CargoBike {
}
fragment CargoBikeFieldsForPage on CargoBike {
...CargoBikeFieldsForTable
bikeEvents {
...BikeEventFieldsForBikePage
}
equipment {
...EquipmentFieldsForBikePage
}
equipmentType {
...EquipmentTypeFields
}
engagement {
...EngagementFieldsForBikePage
}
currentEngagements {
...EngagementFieldsForBikePage
}
timeFrames {
...TimeFrameFieldsForBikePage
...CargoBikeFieldsForTable
bikeEvents {
...BikeEventFieldsForBikePage
}
equipment {
...EquipmentFieldsForBikePage
}
equipmentType {
...EquipmentTypeFields
}
engagement {
...EngagementFieldsForBikePage
}
currentEngagements {
...EngagementFieldsForBikePage
}
timeFrames {
...TimeFrameFieldsForBikePage
}
}
}

@ -1,13 +1,36 @@
fragment TimeFrameFieldsForBikePage on TimeFrame {
id
from
id
dateRange {
from
to
note
lendingStation {
...LendingStationFieldsForBikePage
}
isLocked
}
note
lendingStation {
...LendingStationFieldsForBikePage
}
isLocked
isLockedByMe
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',
@ -227,7 +215,7 @@ export class BikeComponent implements OnInit {
},
linkToTable: (element) => '/table/equipment',
linkToTableParams: (bike) => {
return {filter: bike.name};
return { filter: bike.name };
},
propertyNameOfUpdateInput: 'equipmentIds',
},

@ -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);
}
}
}

File diff suppressed because it is too large Load Diff

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