diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index c7eab73..32199a6 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -1,5 +1,6 @@ import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; +import { BikeComponent } from './pages/dataPages/bike/bike.component'; import { LoginComponent} from './pages/login/login.component' import { TableOverviewComponent } from './pages/table-overview/table-overview.component'; import { BikesComponent} from './pages/tables/bikes/bikes.component' @@ -10,6 +11,7 @@ const routes: Routes = [ { path: 'login', component: LoginComponent }, { path: 'tableOverview', component: TableOverviewComponent }, { path: 'table/bikes', component: BikesComponent }, + { path: 'bike/:id', component: BikeComponent }, { path: 'table/participants', component: ParticipantsComponent }, { path: 'table/lendingStations', component: LendingStationsComponent }, { path: '', redirectTo: 'tableOverview', pathMatch: 'full' }, diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 1937b15..c120085 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -43,7 +43,8 @@ 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 { TokenInterceptor } from './helper/token.interceptor' +import { TokenInterceptor } from './helper/token.interceptor'; +import { BikeComponent } from './pages/dataPages/bike/bike.component' @NgModule({ @@ -57,7 +58,8 @@ import { TokenInterceptor } from './helper/token.interceptor' LendingStationsComponent, TableOverviewComponent, CellComponent, - DeleteConfirmationDialog + DeleteConfirmationDialog, + BikeComponent ], imports: [ BrowserModule, diff --git a/src/app/components/tableComponents/cell/cell.component.html b/src/app/components/tableComponents/cell/cell.component.html index 5751147..b47fdac 100644 --- a/src/app/components/tableComponents/cell/cell.component.html +++ b/src/app/components/tableComponents/cell/cell.component.html @@ -42,6 +42,7 @@ /> - {{ value }} + {{ value }} + {{value}} diff --git a/src/app/components/tableComponents/cell/cell.component.ts b/src/app/components/tableComponents/cell/cell.component.ts index 3b57e6d..b9bf68c 100644 --- a/src/app/components/tableComponents/cell/cell.component.ts +++ b/src/app/components/tableComponents/cell/cell.component.ts @@ -30,6 +30,8 @@ export class CellComponent { } @Input() required: boolean = false; + @Input() + link: string = null; @Output() validityChange = new EventEmitter(); isValid: boolean = true; @@ -39,8 +41,7 @@ export class CellComponent { @ViewChild('input') input: any; - constructor(private cdr: ChangeDetectorRef) { - } + constructor(private cdr: ChangeDetectorRef) {} ngAfterViewInit() { if (this.required) { @@ -53,9 +54,9 @@ export class CellComponent { this.inputType === 'Boolean' && this.editable ) { - setTimeout(()=> { + setTimeout(() => { this.change(false); - }, 0); + }, 0); } } } @@ -78,7 +79,7 @@ export class CellComponent { newValue = newValue.toString().replace('.', ''); } this.value = this.htmlInputType === 'number' ? +newValue : newValue; - if (newValue === "") { + if (newValue === '') { this.value = null; } this.valueChange.emit(this.value); diff --git a/src/app/graphqlOperations/bike.graphql b/src/app/graphqlOperations/bike.graphql index 99e1c23..d9aab0c 100644 --- a/src/app/graphqlOperations/bike.graphql +++ b/src/app/graphqlOperations/bike.graphql @@ -1,30 +1,42 @@ +query GetCargoBikes { + cargoBikes(limit: 1000, offset: 0) { + ...CargoBikeFieldsForTable + } +} + query GetCargoBikeById($id: ID!) { cargoBikeById(id: $id) { - ...CargoBikeFields + ...CargoBikeFieldsForPage + } +} + +query ReloadCargoBikeById($id: ID!) { + cargoBikeById(id: $id) { + ...CargoBikeFieldsForTable } } mutation CreateCargoBike($bike: CargoBikeCreateInput!) { createCargoBike(cargoBike: $bike) { - ...CargoBikeFields + ...CargoBikeFieldsForTable } } mutation UpdateCargoBike($bike: CargoBikeUpdateInput!) { updateCargoBike(cargoBike: $bike) { - ...CargoBikeFields + ...CargoBikeFieldsForTable } } mutation LockCargoBike($id: ID!) { lockCargoBike(id: $id) { - ...CargoBikeFields + ...CargoBikeFieldsForTable } } mutation UnlockCargoBike($id: ID!) { unlockCargoBike(id: $id) { - ...CargoBikeFields + ...CargoBikeFieldsForTable } } diff --git a/src/app/graphqlOperations/bikes.graphql b/src/app/graphqlOperations/bikes.graphql deleted file mode 100644 index eff799c..0000000 --- a/src/app/graphqlOperations/bikes.graphql +++ /dev/null @@ -1,5 +0,0 @@ -query GetCargoBikes { - cargoBikes(limit: 1000, offset: 0) { - ...CargoBikeFields - } -} diff --git a/src/app/graphqlOperations/fragments/address.graphql b/src/app/graphqlOperations/fragments/address.graphql new file mode 100644 index 0000000..5b1c2fb --- /dev/null +++ b/src/app/graphqlOperations/fragments/address.graphql @@ -0,0 +1,5 @@ +fragment AddressFields on Address { + street + number + zip +} \ No newline at end of file diff --git a/src/app/graphqlOperations/fragments/bikeFragment.graphql b/src/app/graphqlOperations/fragments/bike.graphql similarity index 67% rename from src/app/graphqlOperations/fragments/bikeFragment.graphql rename to src/app/graphqlOperations/fragments/bike.graphql index 49a0aa4..fc05c07 100644 --- a/src/app/graphqlOperations/fragments/bikeFragment.graphql +++ b/src/app/graphqlOperations/fragments/bike.graphql @@ -1,4 +1,4 @@ -fragment CargoBikeFieldsMutable on CargoBike { +fragment CargoBikeFieldsForTable on CargoBike { id group name @@ -61,18 +61,36 @@ fragment CargoBikeFieldsMutable on CargoBike { costCenter organisationArea } -} - -fragment CargoBikeFields on CargoBike { - ...CargoBikeFieldsMutable provider { ...ProviderFieldsGeneral } lendingStation { - ...LendingStationFieldsGeneral + ...LendingStationFieldsForBikePage } isLocked isLockedByMe lockedBy lockedUntil } + +fragment CargoBikeFieldsForPage on CargoBike { +...CargoBikeFieldsForTable +bikeEvents { + ...BikeEventFieldsForBikePage +} +equipment(offset: 0, limit: 1000) { + ...EquipmentFieldsForBikePage +} +equipmentType { + ...EquipmentTypeFieldsForBikePage +} +engagement(offset: 0, limit: 1000) { + ...EngagementFieldsForBikePage +} +currentEngagements { + ...EngagementFieldsForBikePage +} +timeFrames { + ...TimeFrameFieldsForBikePage +} +} \ No newline at end of file diff --git a/src/app/graphqlOperations/fragments/bikeEvent.graphql b/src/app/graphqlOperations/fragments/bikeEvent.graphql index 43d7678..293e30b 100644 --- a/src/app/graphqlOperations/fragments/bikeEvent.graphql +++ b/src/app/graphqlOperations/fragments/bikeEvent.graphql @@ -1,12 +1,12 @@ -fragment BikeEventFields on BikeEvent { +fragment BikeEventFieldsForBikePage on BikeEvent { id - date bikeEventType { - id - name - isLocked - isLockedByMe + ...BikeEventTypeFields } + responsible { + ...ParticipantFieldsForBikePage + } + date responsible { id } diff --git a/src/app/graphqlOperations/fragments/bikeEventType.graphql b/src/app/graphqlOperations/fragments/bikeEventType.graphql new file mode 100644 index 0000000..550b51f --- /dev/null +++ b/src/app/graphqlOperations/fragments/bikeEventType.graphql @@ -0,0 +1,7 @@ +fragment BikeEventTypeFields on BikeEventType { + id + name + isLocked + isLockedByMe + lockedUntil +} diff --git a/src/app/graphqlOperations/fragments/contactInformation.graphql b/src/app/graphqlOperations/fragments/contactInformation.graphql new file mode 100644 index 0000000..a785529 --- /dev/null +++ b/src/app/graphqlOperations/fragments/contactInformation.graphql @@ -0,0 +1,16 @@ +fragment ContactInformationFields on ContactInformation { + id + person { + ...PersonFields + } + phone + phone2 + email + email2 + note + + isLocked + isLockedByMe + lockedBy + lockedUntil +} \ No newline at end of file diff --git a/src/app/graphqlOperations/fragments/engagement.graphql b/src/app/graphqlOperations/fragments/engagement.graphql new file mode 100644 index 0000000..ba879ab --- /dev/null +++ b/src/app/graphqlOperations/fragments/engagement.graphql @@ -0,0 +1,15 @@ +fragment EngagementFieldsForBikePage on Engagement { + id + engagementType { + ...EngagementTypeFields + } + from + to + participant { + ...ParticipantFieldsForBikePage + } + isLocked + isLockedByMe + lockedBy + lockedUntil +} \ No newline at end of file diff --git a/src/app/graphqlOperations/fragments/engagementType.graphql b/src/app/graphqlOperations/fragments/engagementType.graphql new file mode 100644 index 0000000..f8e2bbf --- /dev/null +++ b/src/app/graphqlOperations/fragments/engagementType.graphql @@ -0,0 +1,9 @@ +fragment EngagementTypeFields on EngagementType { + id + name + description + isLocked + isLockedByMe + lockedBy + lockedUntil +} \ No newline at end of file diff --git a/src/app/graphqlOperations/fragments/equipment.graphql b/src/app/graphqlOperations/fragments/equipment.graphql new file mode 100644 index 0000000..4e88d4f --- /dev/null +++ b/src/app/graphqlOperations/fragments/equipment.graphql @@ -0,0 +1,10 @@ +fragment EquipmentFieldsForBikePage on Equipment { + id + serialNo + title + description + isLocked + isLockedByMe + lockedBy + lockedUntil +} \ No newline at end of file diff --git a/src/app/graphqlOperations/fragments/equipmentType.graphql b/src/app/graphqlOperations/fragments/equipmentType.graphql new file mode 100644 index 0000000..ac6b084 --- /dev/null +++ b/src/app/graphqlOperations/fragments/equipmentType.graphql @@ -0,0 +1,9 @@ +fragment EquipmentTypeFieldsForBikePage on EquipmentType { + id + name + description + isLocked + isLockedByMe + lockedBy + lockedUntil +} diff --git a/src/app/graphqlOperations/fragments/lendingStation.graphql b/src/app/graphqlOperations/fragments/lendingStation.graphql index fce1933..a6486c5 100644 --- a/src/app/graphqlOperations/fragments/lendingStation.graphql +++ b/src/app/graphqlOperations/fragments/lendingStation.graphql @@ -1,9 +1,10 @@ -fragment LendingStationFieldsGeneral on LendingStation { +fragment LendingStationFieldsForBikePage on LendingStation { id name address { - number - street - zip + ...AddressFields + } + organisation { + ...OrganisationFieldsForTimeFrame } } diff --git a/src/app/graphqlOperations/fragments/organisation.graphql b/src/app/graphqlOperations/fragments/organisation.graphql new file mode 100644 index 0000000..9ebea9c --- /dev/null +++ b/src/app/graphqlOperations/fragments/organisation.graphql @@ -0,0 +1,7 @@ +fragment OrganisationFieldsForTimeFrame on Organisation { + id + name + address { + ...AddressFields + } +} diff --git a/src/app/graphqlOperations/fragments/participant.graphql b/src/app/graphqlOperations/fragments/participant.graphql new file mode 100644 index 0000000..b7eb3b2 --- /dev/null +++ b/src/app/graphqlOperations/fragments/participant.graphql @@ -0,0 +1,15 @@ +fragment ParticipantFieldsForBikePage on Participant { + id + start + end + usernamefLotte + usernameSlack + contactInformation { + ...ContactInformationFields + } + + isLocked + isLockedByMe + lockedBy + lockedUntil +} \ No newline at end of file diff --git a/src/app/graphqlOperations/fragments/person.graphql b/src/app/graphqlOperations/fragments/person.graphql new file mode 100644 index 0000000..4e07d1c --- /dev/null +++ b/src/app/graphqlOperations/fragments/person.graphql @@ -0,0 +1,10 @@ +fragment PersonFields on Person { + id + name + firstName + + isLocked + isLockedByMe + lockedBy + lockedUntil +} \ No newline at end of file diff --git a/src/app/graphqlOperations/fragments/timeFrames.graphql b/src/app/graphqlOperations/fragments/timeFrames.graphql new file mode 100644 index 0000000..caf87b0 --- /dev/null +++ b/src/app/graphqlOperations/fragments/timeFrames.graphql @@ -0,0 +1,13 @@ +fragment TimeFrameFieldsForBikePage on TimeFrame { + id + from + to + note + lendingStation { + ...LendingStationFieldsForBikePage + } + isLocked + isLockedByMe + lockedBy + lockedUntil +} \ No newline at end of file diff --git a/src/app/pages/dataPages/bike/bike.component.html b/src/app/pages/dataPages/bike/bike.component.html new file mode 100644 index 0000000..8539140 --- /dev/null +++ b/src/app/pages/dataPages/bike/bike.component.html @@ -0,0 +1,19 @@ + +
+

Seite konnte nicht gefunden werden :(

+
+
+

{{ data[headlineDataPath] }}

+ +
+ +
+
diff --git a/src/app/pages/dataPages/bike/bike.component.scss b/src/app/pages/dataPages/bike/bike.component.scss new file mode 100644 index 0000000..59a9381 --- /dev/null +++ b/src/app/pages/dataPages/bike/bike.component.scss @@ -0,0 +1,6 @@ +.page-loading-spinner { + margin: 0 auto; +} +.page-wrapper { + padding: 1em; +} \ No newline at end of file diff --git a/src/app/pages/dataPages/bike/bike.component.ts b/src/app/pages/dataPages/bike/bike.component.ts new file mode 100644 index 0000000..9c9c22a --- /dev/null +++ b/src/app/pages/dataPages/bike/bike.component.ts @@ -0,0 +1,150 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { BikesService } from 'src/app/services/bikes.service'; +import { SchemaService } from 'src/app/services/schema.service'; + +@Component({ + selector: 'app-bike', + templateUrl: './bike.component.html', + styleUrls: ['./bike.component.scss'], +}) +export class BikeComponent implements OnInit { + propertiesInfo: { + name: string; + translation: string; + readonly?: boolean; + type?: string; + }[] = [ + { name: 'name', translation: 'Name' }, + { name: 'id', translation: 'ID', readonly: true }, + { name: 'group', translation: 'Gruppe' }, + { name: 'modelName', translation: 'Modell' }, + { name: 'insuranceData.billing', translation: 'Versicherung Abrechnung' }, + { name: 'insuranceData.hasFixedRate', translation: 'Pauschale j/n' }, + { name: 'insuranceData.fixedRate', translation: 'Pauschale Betrag' }, + { name: 'insuranceData.name', translation: 'Versicherer' }, + { name: 'insuranceData.benefactor', translation: 'Kostenträger' }, + { name: 'insuranceData.noPnP', translation: 'Nr. P&P' }, + { + name: 'insuranceData.maintenanceResponsible', + translation: 'Wartung zuständig', + }, + { + name: 'insuranceData.maintenanceBenefactor', + translation: 'Wartung Kostenträger', + }, + { + name: 'insuranceData.maintenanceAgreement', + translation: 'Wartungsvereinbarung', + }, + { name: 'insuranceData.projectAllowance', translation: 'Projektzuschuss' }, + { name: 'insuranceData.notes', translation: 'Sonstiges' }, + { name: 'dimensionsAndLoad.bikeLength', translation: 'Länge' }, + { name: 'dimensionsAndLoad.bikeWeight', translation: 'Gewicht' }, + { name: 'dimensionsAndLoad.bikeHeight', translation: 'Höhe' }, + { name: 'dimensionsAndLoad.bikeWidth', translation: 'Breite' }, + { name: 'dimensionsAndLoad.boxHeight', translation: 'Boxhöhe' }, + { name: 'dimensionsAndLoad.boxLength', translation: 'Boxlänge' }, + { name: 'dimensionsAndLoad.boxWidth', translation: 'Boxbreite' }, + { name: 'dimensionsAndLoad.hasCoverBox', translation: 'Boxabdeckung j/n' }, + { name: 'dimensionsAndLoad.lockable', translation: 'Box abschließbar' }, + { name: 'dimensionsAndLoad.maxWeightBox', translation: 'max Zuladung Box' }, + { + name: 'dimensionsAndLoad.maxWeightLuggageRack', + translation: 'max Zuladung Gepäckträger', + }, + { + name: 'dimensionsAndLoad.maxWeightTotal', + translation: 'max Gesamtgewicht', + }, + { name: 'numberOfChildren', translation: 'Anzahl Kinder' }, + { name: 'numberOfWheels', translation: 'Anzahl Räder' }, + { name: 'forCargo', translation: 'für Lasten j/n' }, + { name: 'forChildren', translation: 'für Kinder j/n' }, + { name: 'security.frameNumber', translation: 'Rahmennummer' }, + { name: 'security.adfcCoding', translation: 'ADFC Codierung' }, + { + name: 'security.keyNumberAXAChain', + translation: 'Schlüsselnrummer Rahmenschloss', + }, + { + name: 'security.keyNumberFrameLock', + translation: 'Schlüsselnrummer AXA-Kette', + }, + { name: 'security.policeCoding', translation: 'Polizei Codierung' }, + { name: 'technicalEquipment.bicycleShift', translation: 'Schaltung' }, + { name: 'technicalEquipment.isEBike', translation: 'E-Bike j/n' }, + { + name: 'technicalEquipment.hasLightSystem', + translation: 'Lichtanlage j/n', + }, + { + name: 'technicalEquipment.specialFeatures', + translation: 'Besonderheiten', + }, + { name: 'stickerBikeNameState', translation: 'Aufkleber Status' }, + { name: 'note', translation: 'Aufkleber Kommentar' }, + { name: 'taxes.costCenter', translation: 'Steuern Kostenstelle' }, + { name: 'taxes.organisationArea', translation: 'Steuern Vereinsbereich' }, + { name: 'provider.id', translation: '' }, + { name: 'provider.formName', translation: '' }, + { name: 'provider.privatePerson.id', translation: '' }, + { name: 'provider.privatePerson.person.id', translation: '' }, + { name: 'provider.privatePerson.person.name', translation: '' }, + { name: 'provider.privatePerson.person.firstName', translation: '' }, + { + name: 'provider.privatePerson.person.contactInformation.email', + translation: '', + }, + { name: 'lendingStation.id', translation: '' }, + { name: 'lendingStation.name', translation: '' }, + { name: 'lendingStation.address.number', translation: '' }, + { name: 'lendingStation.address.street', translation: '' }, + { name: 'lendingStation.address.zip', translation: '' }, + ]; + + headlineDataPath = 'name'; + pageDataGQLType: string = "CargoBike"; + pageDataGQLUpdateInputType: string = "CargoBikeUpdateInput" + + id: string; + data: any; + isLoading: boolean = false; + + constructor( + private route: ActivatedRoute, + private bikesService: BikesService, + private schemaService: SchemaService + ) { + this.addPropertiesFromGQLSchemaToPropertiesInfo(); + console.log(this.propertiesInfo); + } + + ngOnInit(): void { + this.id = this.route.snapshot.paramMap.get('id'); + this.bikesService.loadCargoBike({ id: this.id }); + this.bikesService.bike.subscribe((data) => { + this.data = data; + }); + this.bikesService.loadingBike.subscribe( + (isLoading) => (this.isLoading = isLoading) + ); + } + + addPropertiesFromGQLSchemaToPropertiesInfo() { + for (const column of this.propertiesInfo) { + const typeInformation = this.schemaService.getTypeInformation( + this.pageDataGQLType, + column.name + ); + column.type = column.type || typeInformation.type; + } + for (const column of this.propertiesInfo) { + const typeInformation = this.schemaService.getTypeInformation( + this.pageDataGQLUpdateInputType, + column.name + ); + column.readonly = column.readonly || !typeInformation.isPartOfType; + } + } +} diff --git a/src/app/pages/tables/bikes/bikes.component.html b/src/app/pages/tables/bikes/bikes.component.html index 61e0afb..a835b0d 100644 --- a/src/app/pages/tables/bikes/bikes.component.html +++ b/src/app/pages/tables/bikes/bikes.component.html @@ -44,9 +44,13 @@ [disabled]="reloadingTable" i18n > - {{countUnsavedRows()}} ungespeicherte(s) Element(e) anzeigen + {{ countUnsavedRows() }} ungespeicherte(s) Element(e) anzeigen - + nur ungespeicherte Elemente anzeigen - {{ element[column.name] }} + + {{ element[column.name] }} + {{ + element[column.name] + }} + + @@ -188,7 +199,8 @@ class="button-wrapper" *ngIf="element.newObject" [matTooltip]=" - 'Nicht ausgefüllte Pflichtfelder (rot): ' + countUnvalidFields(element) + 'Nicht ausgefüllte Pflichtfelder (rot): ' + + countUnvalidFields(element) " >