Add multiple tables

master
Max 3 years ago
parent 5c5bd4b642
commit 92614daff7

@ -20,6 +20,14 @@ import { ProvidersComponent } from './pages/tables/providers/providers.component
import { PersonComponent } from './pages/dataPages/person/person.component';
import { OrganisationComponent } from './pages/dataPages/organisation/organisation.component';
import { ProviderComponent } from './pages/dataPages/provider/provider.component';
import { ParticipantComponent } from './pages/dataPages/participant/participant.component';
import { WorkshopComponent } from './pages/dataPages/workshop/workshop.component';
import { WorkshopsComponent } from './pages/tables/workshops/workshops.component';
import { WorkshopTypesComponent } from './pages/tables/workshop-types/workshop-types.component';
import { EngagementsComponent } from './pages/tables/engagements/engagements.component';
import { BikeEventsComponent } from './pages/tables/bike-events/bike-events.component';
import { BikeEventComponent } from './pages/dataPages/bike-event/bike-event.component';
import { BikeEventTypesComponent } from './pages/tables/bike-event-types/bike-event-types.component';
const routes: Routes = [
{ path: 'login', component: LoginComponent },
@ -27,11 +35,15 @@ const routes: Routes = [
{ path: 'profile', component: ProfileComponent, canActivate: [AuthGuard]},
{ path: 'table/bikes', component: BikesComponent, canActivate: [AuthGuard] },
{ path: 'bike/:id', component: BikeComponent, canActivate: [AuthGuard] },
{ path: 'table/bikeEvents', component: BikeEventsComponent, canActivate: [AuthGuard] },
{ path: 'bikeEvent/:id', component: BikeEventComponent, canActivate: [AuthGuard] },
{ path: 'table/bikeEventTypes', component: BikeEventTypesComponent, canActivate: [AuthGuard] },
{ path: 'table/participants', component: ParticipantsComponent, canActivate: [AuthGuard] },
{ path: 'table/lendingStations', component: LendingStationsComponent, canActivate: [AuthGuard] },
{ path: 'table/equipmentTypes', component: EquipmentTypesComponent, canActivate: [AuthGuard] },
{ path: 'table/engagementTypes', component: EngagementTypesComponent, canActivate: [AuthGuard] },
{ path: 'table/equipment', component: EquipmentComponent, canActivate: [AuthGuard] },
{ path: 'table/engagements', component: EngagementsComponent, canActivate: [AuthGuard] },
{ path: 'table/equipments', component: EquipmentComponent, canActivate: [AuthGuard] },
{ path: 'table/timeFrames', component: TimeFramesComponent, canActivate: [AuthGuard] },
{ path: 'table/persons', component: PersonsComponent, canActivate: [AuthGuard] },
{ path: 'table/contactInformation', component: ContactInformationComponent, canActivate: [AuthGuard] },
@ -41,6 +53,11 @@ const routes: Routes = [
{ path: 'person/:id', component: PersonComponent, canActivate: [AuthGuard] },
{ path: 'provider/:id', component: ProviderComponent, canActivate: [AuthGuard] },
{ path: 'organisation/:id', component: OrganisationComponent, canActivate: [AuthGuard] },
{ path: 'participant/:id', component: ParticipantComponent, canActivate: [AuthGuard] },
{ path: 'participants', component: ParticipantsComponent, canActivate: [AuthGuard] },
{ path: 'workshop/:id', component: WorkshopComponent, canActivate: [AuthGuard] },
{ path: 'table/workshops', component: WorkshopsComponent, canActivate: [AuthGuard] },
{ path: 'table/workshopTypes', component: WorkshopTypesComponent, canActivate: [AuthGuard] },
{ path: '', redirectTo: 'tableOverview', pathMatch: 'full' },
{ path: 'table', redirectTo: 'tableOverview', pathMatch: 'full' },
{ path: '**', redirectTo: 'tableOverview' },

@ -6,7 +6,7 @@ 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'
import { DatePipe } from '@angular/common';
// Angular Material Components
import { MatToolbarModule } from '@angular/material/toolbar';
@ -32,6 +32,7 @@ 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 { MatChipsModule } from '@angular/material/chips';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
@ -66,7 +67,10 @@ import { SelectObjectDialogComponent } from './components/select-object-dialog/s
import { AutocompleteSelectComponent } from './components/autocomplete-select/autocomplete-select.component';
import { LendingStationComponent } from './pages/dataPages/lending-station/lending-station.component';
import { ProfileComponent } from './pages/profile/profile.component';
import { ErrorSnackbarComponent, SnackbarDialog } from './helper/snackbar-ref.component';
import {
ErrorSnackbarComponent,
SnackbarDialog,
} from './helper/snackbar-ref.component';
import { HttpLinkModule } from 'apollo-angular-link-http';
import { PersonsComponent } from './pages/tables/persons/persons.component';
import { ContactInformationComponent } from './pages/tables/contact-information/contact-information.component';
@ -75,8 +79,13 @@ import { ProvidersComponent } from './pages/tables/providers/providers.component
import { OrganisationComponent } from './pages/dataPages/organisation/organisation.component';
import { PersonComponent } from './pages/dataPages/person/person.component';
import { ProviderComponent } from './pages/dataPages/provider/provider.component';
import { WorkshopComponent } from './pages/dataPages/workshop/workshop.component';
import { BikeEventComponent } from './pages/dataPages/bike-event/bike-event.component';
import { ParticipantComponent } from './pages/dataPages/participant/participant.component';
import { EngagementsComponent } from './pages/tables/engagements/engagements.component';
import { BikeEventsComponent } from './pages/tables/bike-events/bike-events.component';
import { BikeEventTypesComponent } from './pages/tables/bike-event-types/bike-event-types.component';
import { WorkshopTypesComponent } from './pages/tables/workshop-types/workshop-types.component';
@NgModule({
declarations: [
@ -113,7 +122,14 @@ import { ProviderComponent } from './pages/dataPages/provider/provider.component
ProvidersComponent,
OrganisationComponent,
PersonComponent,
ProviderComponent
ProviderComponent,
WorkshopComponent,
BikeEventComponent,
ParticipantComponent,
EngagementsComponent,
BikeEventsComponent,
BikeEventTypesComponent,
WorkshopTypesComponent,
],
imports: [
BrowserModule,
@ -149,7 +165,8 @@ import { ProviderComponent } from './pages/dataPages/provider/provider.component
MatDialogModule,
MatAutocompleteModule,
MatDatepickerModule,
MatNativeDateModule
MatNativeDateModule,
MatChipsModule,
],
providers: [
NavService,
@ -157,8 +174,8 @@ import { ProviderComponent } from './pages/dataPages/provider/provider.component
MatDatepickerModule,
DatePipe,
{ provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true },
{provide: MAT_DATE_LOCALE, useValue: 'de-DE'},
{ provide: MAT_DATE_LOCALE, useValue: 'de-DE' },
],
bootstrap: [AppComponent],

@ -1,7 +1,7 @@
<div class="table-page-wrapper">
<h1 class="headline" *ngIf="headline">
{{ headline }}
<mat-icon>{{headlineIconName}}</mat-icon>
<mat-icon>{{ headlineIconName }}</mat-icon>
</h1>
<div class="table-control">
<!--<button
@ -116,7 +116,11 @@
<th mat-header-cell *matHeaderCellDef mat-sort-header>
{{ getTranslation(column.dataPath) }}
</th>
<td mat-cell *matCellDef="let element" [ngClass]="{'highlighted-column': column.highlighted}" >
<td
mat-cell
*matCellDef="let element"
[ngClass]="{ 'highlighted-column': column.highlighted }"
>
<ng-container
*ngIf="
column.type !== 'DateRange' &&
@ -127,6 +131,8 @@
<app-cell
*ngIf="
column.type === 'Boolean' ||
column.type === 'Date' ||
column.list ||
(element.newObject && column.acceptedForCreation) ||
(column.acceptedForUpdating && element.isLockedByMe);
else stringValue
@ -143,6 +149,7 @@
validityChange(element, column.dataPath, $event)
"
[(value)]="element[column.dataPath]"
[isList]="column.list"
[inputType]="column.type"
[link]="column.link ? column.link(element) : null"
></app-cell>
@ -198,7 +205,10 @@
else stringValue
"
>
<button mat-button (click)="openSelectObjectDialog(element, column)">
<button
mat-button
(click)="openSelectObjectDialog(element, column)"
>
{{ element[column.dataPath] }}
<mat-icon>expand_more</mat-icon>
</button>

@ -46,6 +46,7 @@ export class TableComponent implements AfterViewInit {
requiredForUpdating?: boolean;
required?: boolean;
type?: string;
list?: boolean; //whether the type is a list
link?: (row: any) => string;
highlighted: boolean; // whether this column is a bit darker
}[] = [];
@ -206,6 +207,7 @@ export class TableComponent implements AfterViewInit {
column.dataPath
);
column.type = column.type || typeInformation.type;
column.list = typeInformation.isList;
column.required =
column.required != null ? column.required : typeInformation.isRequired;

@ -10,6 +10,37 @@
>
</div>
<div *ngIf="htmlInputType === 'date'" [formGroup]="dateGroup">
<mat-form-field *ngIf="editable || label; else nonEditableText">
<mat-label *ngIf="label">{{ label }}</mat-label>
<input
matInput
[matDatepicker]="picker"
required
disabled
(dateChange)="dateChange($event)"
[value]="stringToDate(value)"
formControlName="dateControl"
/>
<button
mat-button
*ngIf="editable && value"
matSuffix
mat-icon-button
aria-label="Clear"
(click)="dateChange({ value: null })"
>
<mat-icon>close</mat-icon>
</button>
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker [disabled]="!editable"></mat-datepicker>
</mat-form-field>
<ng-template #nonEditableText>
{{ toLocaleDate(stringToDate(value)) }}
</ng-template>
</div>
<div #enumInputType *ngIf="htmlInputType === 'enum'">
<mat-form-field *ngIf="editable || label; else nonEditableText">
<mat-label *ngIf="label">{{ label }}</mat-label>
@ -30,6 +61,62 @@
</ng-template>
</div>
<div #enumInputType *ngIf="htmlInputType === 'stringList'">
<mat-form-field *ngIf="editable || label; else nonEditableText">
<mat-label *ngIf="label">{{ label }}</mat-label>
<mat-chip-list #chipList>
<mat-chip
*ngFor="let element of value"
[removable]="true"
(removed)="removeElementFromList(element)"
>
{{ element }}
<mat-icon matChipRemove>cancel</mat-icon>
</mat-chip>
<input
placeholder="hinzufügen..."
[matChipInputFor]="chipList"
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
[matChipInputAddOnBlur]="true"
(matChipInputTokenEnd)="addElementToList($event)"
/>
</mat-chip-list>
</mat-form-field>
<ng-template #nonEditableText>
{{ value.join(", ") }}
</ng-template>
</div>
<div #enumInputType *ngIf="htmlInputType === 'linkList'">
<mat-form-field *ngIf="editable || label; else nonEditableText">
<mat-label *ngIf="label">{{ label }}</mat-label>
<mat-chip-list #chipList>
<mat-chip
*ngFor="let element of value"
[removable]="true"
(removed)="removeElementFromList(element)"
>
{{ element }}
<mat-icon matChipRemove>cancel</mat-icon>
</mat-chip>
<input
placeholder="hinzufügen..."
[matChipInputFor]="chipList"
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
[matChipInputAddOnBlur]="true"
(matChipInputTokenEnd)="addElementToList($event)"
/>
</mat-chip-list>
</mat-form-field>
<ng-template #nonEditableText>
<ng-container *ngFor="let link of value">
<a mat-button color="primary" [href]="link">{{
link
}}</a>
</ng-container>
</ng-template>
</div>
<div
#otherInputType
*ngIf="htmlInputType === 'number' || htmlInputType === 'text'"

@ -1,4 +1,5 @@
import { DatePipe } from '@angular/common';
import { COMMA, ENTER } from '@angular/cdk/keycodes';
import {
Component,
Input,
@ -8,6 +9,8 @@ import {
ChangeDetectorRef,
AfterViewInit,
} from '@angular/core';
import { MatChipInputEvent } from '@angular/material/chips';
import { FormControl, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'app-cell',
@ -25,9 +28,9 @@ export class CellComponent implements AfterViewInit {
get value(): any {
return this._value;
}
_value: number | string | boolean;
_value: number | string | boolean | [];
@Output() valueChange = new EventEmitter<number | string | boolean>();
@Output() valueChange = new EventEmitter<number | string | boolean | []>();
@Input()
set editable(value: boolean) {
this._editable = value;
@ -64,6 +67,8 @@ export class CellComponent implements AfterViewInit {
@Input()
link: string = null;
@Input()
isList: boolean;
@Input()
label: string = null;
@Output() validityChange = new EventEmitter<boolean>();
isValid = true;
@ -73,14 +78,26 @@ export class CellComponent implements AfterViewInit {
htmlInputType = 'string';
@ViewChild('input') input: any;
dateGroup: FormGroup;
readonly separatorKeysCodes: number[] = [ENTER, COMMA];
constructor(private cdr: ChangeDetectorRef, public datepipe: DatePipe) {}
ngOnInit() {}
ngOnInit() {
if(this.htmlInputType === "date") {
this.dateGroup = new FormGroup({
dateControl: new FormControl(),
});
this.dateGroup.controls['dateControl'].markAsTouched();
}
}
ngAfterViewInit(): void {
if (this.required) {
this.input?.control?.markAsTouched();
this.checkIfValid();
this.cdr.detectChanges();
@ -89,6 +106,7 @@ export class CellComponent implements AfterViewInit {
this.change(false);
});
}
}
}
@ -100,12 +118,22 @@ export class CellComponent implements AfterViewInit {
this.htmlInputType = 'number';
} else if (type === 'ID' || type === 'String') {
this.htmlInputType = 'text';
if (this.isList) {
this.htmlInputType = 'stringList';
}
} else if (type === 'Boolean') {
this.htmlInputType = 'boolean';
} else if (type === 'Date') {
this.htmlInputType = 'date';
} else if (type === 'DateRange') {
this.htmlInputType = 'dateRange';
} else if (type === 'Link') {
this.htmlInputType = 'link';
if (this.isList) {
this.htmlInputType = 'linkList';
}
} else {
console.error('Cell got invalid type: ' + type);
}
}
@ -120,13 +148,78 @@ export class CellComponent implements AfterViewInit {
this.valueChange.emit(this.value);
this.checkIfValid();
}
addElementToList(event: MatChipInputEvent): void {
const input = event.input;
const value = event.value;
if (this.value == null) {
this.value = [];
}
// Add element
if ((value || '').trim()) {
this.value.push(value.trim());
}
// Reset the input value
if (input) {
input.value = '';
}
this.valueChange.emit(this.value);
}
removeElementFromList(string: string): void {
const index = this.value.indexOf(string);
if (index >= 0) {
this.value.splice(index, 1);
}
this.valueChange.emit(this.value);
}
checkIfValid() {
setTimeout(() => {
if (this.editable && this.required && this.inputType !== 'Boolean') {
if (!this.value && this.isList) {
this.value = [];
this.valueChange.emit([]);
} else if (this.editable &&
this.required && this.htmlInputType === "date") {
const dateIsEmpty = !this.value;
this.isValid = !dateIsEmpty;
this.validityChange.emit(this.isValid);
if (dateIsEmpty) {
this.dateGroup.controls['dateControl'].setErrors({ rangeError: true });
} else {
this.dateGroup.controls['dateControl'].setErrors(null);
}
} else if (
this.editable &&
this.required &&
this.inputType !== 'Boolean' &&
!this.isList
) {
this.isValid = this.input?.control?.valid || false;
this.validityChange.emit(this.isValid);
}
});
}
dateChange(event) {
this.value = this.transformDate(event.value)
this.valueChange.emit(this.value);
this.checkIfValid();
}
transformDate(date) {
return this.datepipe.transform(date, 'yyyy-MM-dd');
}
toLocaleDate(date: string): string {
if (date == '') {
return '';
}
return new Date(date).toLocaleDateString();
}
stringToDate(dateString: string): Date {
if (!dateString) return null;
return new Date(dateString) || null;
}
}

@ -0,0 +1,45 @@
query GetBikeEvents {
bikeEvents {
...BikeEventFieldsForTable
}
}
query GetBikeEventById($id: ID!) {
bikeEventById(id: $id) {
...BikeEventFieldsForPage
}
}
query ReloadBikeEventById($id: ID!) {
bikeEventById(id: $id) {
...BikeEventFieldsForTable
}
}
mutation CreateBikeEvent($bikeEvent: BikeEventCreateInput!) {
createBikeEvent(bikeEvent: $bikeEvent) {
...BikeEventFieldsForTable
}
}
mutation UpdateBikeEvent($bikeEvent: BikeEventUpdateInput!) {
updateBikeEvent(bikeEvent: $bikeEvent) {
...BikeEventFieldsForPage
}
}
mutation LockBikeEvent($id: ID!) {
lockBikeEvent(id: $id) {
...BikeEventFieldsForPage
}
}
mutation UnlockBikeEvent($id: ID!) {
unlockBikeEvent(id: $id) {
...BikeEventFieldsForPage
}
}
mutation DeleteBikeEvent($id: ID!) {
deleteBikeEvent(id: $id)
}

@ -0,0 +1,33 @@
query GetBikeEventTypes {
bikeEventTypes {
...BikeEventTypeFields
}
}
mutation CreateBikeEventType($bikeEventType: String!) {
createBikeEventType(name: $bikeEventType) {
...BikeEventTypeFields
}
}
mutation UpdateBikeEventType($bikeEventType: BikeEventTypeUpdateInput!) {
updateBikeEventType(bikeEventType: $bikeEventType) {
...BikeEventTypeFields
}
}
mutation LockBikeEventType($id: ID!) {
lockBikeEventType(id: $id) {
...BikeEventTypeFields
}
}
mutation UnlockBikeEventType($id: ID!) {
unlockBikeEventType(id: $id) {
...BikeEventTypeFields
}
}
mutation DeleteBikeEventType($id: ID!) {
deleteBikeEventType(id: $id)
}

@ -0,0 +1,33 @@
query GetEngagements {
engagements {
...EngagementFields
}
}
mutation CreateEngagement($engagement: EngagementCreateInput!) {
createEngagement(engagement: $engagement) {
...EngagementFields
}
}
mutation UpdateEngagement($engagement: EngagementUpdateInput!) {
updateEngagement(engagement: $engagement) {
...EngagementFields
}
}
mutation LockEngagement($id: ID!) {
lockEngagement(id: $id) {
...EngagementFields
}
}
mutation UnlockEngagement($id: ID!) {
unlockEngagement(id: $id) {
...EngagementFields
}
}
mutation DeleteEngagement($id: ID!) {
deleteEngagement(id: $id)
}

@ -0,0 +1,33 @@
query GetEngagementTypes {
engagementTypes {
...EngagementTypeFields
}
}
mutation CreateEngagementType($engagementType: EngagementTypeCreateInput!) {
createEngagementType(engagementType: $engagementType) {
...EngagementTypeFields
}
}
mutation UpdateEngagementType($engagementType: EngagementTypeUpdateInput!) {
updateEngagementType(engagementType: $engagementType) {
...EngagementTypeFields
}
}
mutation LockEngagementType($id: ID!) {
lockEngagementType(id: $id) {
...EngagementTypeFields
}
}
mutation UnlockEngagementType($id: ID!) {
unlockEngagementType(id: $id) {
...EngagementTypeFields
}
}
mutation DeleteEngagementType($id: ID!) {
deleteEngagementType(id: $id)
}

@ -34,3 +34,7 @@ fragment BikeEventFieldsForTable on BikeEvent {
lockedBy
lockedUntil
}
fragment BikeEventFieldsForPage on BikeEvent {
...BikeEventFieldsForTable
}

@ -31,3 +31,25 @@ fragment EngagementFieldsForParticipant on Engagement {
name
}
}
fragment EngagementFields on Engagement {
id
engagementType {
...EngagementTypeFields
}
dateRange {
from
to
}
participant {
...ParticipantFieldsGeneral
}
cargoBike {
id
name
}
isLocked
isLockedByMe
lockedBy
lockedUntil
}

@ -24,4 +24,8 @@ fragment WorkshopFieldsForTable on Workshop {
isLockedByMe
lockedBy
lockedUntil
}
fragment WorkshopFieldsForPage on Workshop {
...WorkshopFieldsForTable
}

@ -3,7 +3,7 @@ fragment WorkshopTypefieldsGeneral on WorkshopType {
name
}
fragment WorkshopTypefieldsForTable on WorkshopType {
fragment WorkshopTypeFields on WorkshopType {
...WorkshopTypefieldsGeneral
isLocked
isLockedByMe

@ -0,0 +1,45 @@
query GetParticipants {
participants {
...ParticipantFieldsForTable
}
}
query GetParticipantById($id: ID!) {
participantById(id: $id) {
...ParticipantFieldsForPage
}
}
query ReloadParticipantById($id: ID!) {
participantById(id: $id) {
...ParticipantFieldsForTable
}
}
mutation CreateParticipant($participant: ParticipantCreateInput!) {
createParticipant(participant: $participant) {
...ParticipantFieldsForTable
}
}
mutation UpdateParticipant($participant: ParticipantUpdateInput!) {
updateParticipant(participant: $participant) {
...ParticipantFieldsForPage
}
}
mutation LockParticipant($id: ID!) {
lockParticipant(id: $id) {
...ParticipantFieldsForPage
}
}
mutation UnlockParticipant($id: ID!) {
unlockParticipant(id: $id) {
...ParticipantFieldsForPage
}
}
mutation DeleteParticipant($id: ID!) {
deleteParticipant(id: $id)
}

@ -0,0 +1,45 @@
query GetWorkshops {
workshops {
...WorkshopFieldsForTable
}
}
query GetWorkshopById($id: ID!) {
workshopById(id: $id) {
...WorkshopFieldsForPage
}
}
query ReloadWorkshopById($id: ID!) {
workshopById(id: $id) {
...WorkshopFieldsForTable
}
}
mutation CreateWorkshop($workshop: WorkshopCreateInput!) {
createWorkshop(workshop: $workshop) {
...WorkshopFieldsForTable
}
}
mutation UpdateWorkshop($workshop: WorkshopUpdateInput!) {
updateWorkshop(workshop: $workshop) {
...WorkshopFieldsForPage
}
}
mutation LockWorkshop($id: ID!) {
lockWorkshop(id: $id) {
...WorkshopFieldsForPage
}
}
mutation UnlockWorkshop($id: ID!) {
unlockWorkshop(id: $id) {
...WorkshopFieldsForPage
}
}
mutation DeleteWorkshop($id: ID!) {
deleteWorkshop(id: $id)
}

@ -0,0 +1,33 @@
query GetWorkshopTypes {
workshopTypes {
...WorkshopTypeFields
}
}
mutation CreateWorkshopType($workshopType: WorkshopTypeCreateInput!) {
createWorkshopType(workshopType: $workshopType) {
...WorkshopTypeFields
}
}
mutation UpdateWorkshopType($workshopType: WorkshopTypeUpdateInput!) {
updateWorkshopType(workshopType: $workshopType) {
...WorkshopTypeFields
}
}
mutation LockWorkshopType($id: ID!) {
lockWorkshopType(id: $id) {
...WorkshopTypeFields
}
}
mutation UnlockWorkshopType($id: ID!) {
unlockWorkshopType(id: $id) {
...WorkshopTypeFields
}
}
mutation DeleteWorkshopType($id: ID!) {
deleteWorkshopType(id: $id)
}

@ -5,7 +5,11 @@ export function flatten(object: Object, prefix: string = ''): any {
if (Array.isArray(object[prop])) {
newObject[propName] = [];
for (const arrayElement of object[prop]) {
newObject[propName].push(flatten(arrayElement));
if (typeof arrayElement === 'object' && arrayElement !== null) {
newObject[propName].push(flatten(arrayElement));
} else {
newObject[propName].push(arrayElement);
}
}
} else if (typeof object[prop] === 'object' && object[prop] !== null) {
const flattenedObject = flatten(object[prop], propName + '.');

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { BikeEventComponent } from './bike-event.component';
describe('BikeEventComponent', () => {
let component: BikeEventComponent;
let fixture: ComponentFixture<BikeEventComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ BikeEventComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(BikeEventComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-bike-event',
templateUrl: './bike-event.component.html',
styleUrls: ['./bike-event.component.scss']
})
export class BikeEventComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}

@ -19,7 +19,7 @@ export class OrganisationComponent implements OnInit {
{ dataPath: 'address.zip', translation: 'Postleitzahl' },
{ dataPath: 'associationNo', translation: 'Vereinsnummer' },
{ dataPath: 'registeredAt', translation: 'Eingetragen seit' },
{ dataPath: 'registeredAt', translation: 'Registergericht' },
],
},
{

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ParticipantComponent } from './participant.component';
describe('ParticipantComponent', () => {
let component: ParticipantComponent;
let fixture: ComponentFixture<ParticipantComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ParticipantComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ParticipantComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-participant',
templateUrl: './participant.component.html',
styleUrls: ['./participant.component.scss']
})
export class ParticipantComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { WorkshopComponent } from './workshop.component';
describe('WorkshopComponent', () => {
let component: WorkshopComponent;
let fixture: ComponentFixture<WorkshopComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ WorkshopComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(WorkshopComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

@ -0,0 +1,15 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-workshop',
templateUrl: './workshop.component.html',
styleUrls: ['./workshop.component.scss']
})
export class WorkshopComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}

@ -17,8 +17,8 @@
<mat-grid-tile class="mat-elevation-z4" routerLink = "/table/providers">Anbieter</mat-grid-tile>
<mat-grid-tile class="mat-elevation-z4" routerLink = "/table/engagements">Engagements</mat-grid-tile>
<mat-grid-tile class="mat-elevation-z4" routerLink = "/table/engagementTypes">Engagementtypen</mat-grid-tile>
<mat-grid-tile class="mat-elevation-z4" routerLink = "/table/bikesEvents">Lastenradevents</mat-grid-tile>
<mat-grid-tile class="mat-elevation-z4" routerLink = "/table/bikesEventTypes">Lastenradeventtypen</mat-grid-tile>
<mat-grid-tile class="mat-elevation-z4" routerLink = "/table/bikeEvents">Lastenradevents</mat-grid-tile>
<mat-grid-tile class="mat-elevation-z4" routerLink = "/table/bikeEventTypes">Lastenradeventtypen</mat-grid-tile>
<mat-grid-tile class="mat-elevation-z4" routerLink = "/table/workshops">Workshops</mat-grid-tile>
<mat-grid-tile class="mat-elevation-z4" routerLink = "/table/workshopTypes">Workshoptypen</mat-grid-tile>
</mat-grid-list>

@ -0,0 +1,14 @@
<app-table
[headline]="headline"
[headlineIconName]="headlineIconName"
[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,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { BikeEventTypesComponent } from './bike-event-types.component';
describe('BikeEventTypesComponent', () => {
let component: BikeEventTypesComponent;
let fixture: ComponentFixture<BikeEventTypesComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ BikeEventTypesComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(BikeEventTypesComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

@ -0,0 +1,54 @@
import { Component, OnInit } from '@angular/core';
import { BikeEventTypesService } from 'src/app/services/bikeEventType.service';
@Component({
selector: 'app-bike-event-types',
templateUrl: './bike-event-types.component.html',
styleUrls: ['./bike-event-types.component.scss'],
})
export class BikeEventTypesComponent implements OnInit {
columnInfo = [
{
dataPath: 'name',
translation: 'Name',
},
];
dataService: any;
tableDataGQLType: string = 'BikeEventType';
tableDataGQLCreateInputType: string = 'BikeEventTypeCreateInput';
tableDataGQLUpdateInputType: string = 'BikeEventTypeUpdateInput';
headline = 'Lastenradeventtypen';
headlineIconName = 'build';
loadingRowIds: string[] = [];
constructor(private BikeEventTypeTypesService: BikeEventTypesService) {}
ngOnInit() {
this.dataService = this.BikeEventTypeTypesService;
}
create(object: { currentId: string; row: any }) {
this.BikeEventTypeTypesService.create(object.currentId, {
bikeEventType: object.row,
});
}
lock(row: any) {
this.BikeEventTypeTypesService.lock({ id: row.id });
}
save(row: any) {
this.BikeEventTypeTypesService.update({ bikeEventType: row });
}
cancel(row: any) {
this.BikeEventTypeTypesService.unlock({ id: row.id });
}
delete(row: any) {
this.BikeEventTypeTypesService.delete({ id: row.id });
}
}

@ -0,0 +1,14 @@
<app-table
[headline]="headline"
[headlineIconName]="headlineIconName"
[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,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { BikeEventsComponent } from './bike-events.component';
describe('BikeEventsComponent', () => {
let component: BikeEventsComponent;
let fixture: ComponentFixture<BikeEventsComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ BikeEventsComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(BikeEventsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

@ -0,0 +1,181 @@
import { Component, OnInit } from '@angular/core';
import { BikeEventTypesService } from 'src/app/services/bikeEventType.service';
import { BikeEventsService } from 'src/app/services/bikeEvent.service';
import { ParticipantsService } from 'src/app/services/participants.service';
import { BikesService } from 'src/app/services/bikes.service';
@Component({
selector: 'app-bike-events',
templateUrl: './bike-events.component.html',
styleUrls: ['./bike-events.component.scss'],
})
export class BikeEventsComponent implements OnInit {
columnInfo = [
{
dataPath: 'bikeEventType.name',
translation: 'Eventtyp',
possibleObjects: [],
nameToShowInSelection: (bikeEventType) => {
return bikeEventType.name || '';
},
propertyPrefixToOverwrite: 'bikeEventType',
currentlySelectedObjectId: (provider) => {
return provider['bikeEventType.id'];
},
propertyNameOfReferenceId: 'bikeEventTypeId',
},
{ dataPath: 'date', translation: 'Datum' },
{
dataPath: 'responsible.contactInformation.person.firstName',
translation: 'Verantwortlicher Vorname',
link: (row: any) => {
return '/participant/' + row['responsible.id'];
},
},
{
dataPath: 'responsible.contactInformation.person.name',
translation: 'Verantwortlicher Nachname',
link: (row: any) => {
return '/participant/' + row['responsible.id'];
},
possibleObjects: [],
nameToShowInSelection: (participant) => {
return (
(participant.contactInformation.person.firstName || '') +
' ' +
(participant.contactInformation.person.name || '') +
' ' +
(participant.contactInformation.email || '') +
' ' +
(participant.contactInformation.phone || '') +
' ' +
(participant.contactInformation.note || '')
);
},
propertyPrefixToOverwrite: 'responsible',
currentlySelectedObjectId: (provider) => {
return provider['responsible.id'];
},
propertyNameOfReferenceId: 'responsibleId',
},
{
dataPath: 'related.contactInformation.person.firstName',
translation: 'Mitarbeiter Vorname',
link: (row: any) => {
return '/participant/' + row['related.id'];
},
},
{
dataPath: 'related.contactInformation.person.name',
translation: 'Mitarbeiter Nachname',
link: (row: any) => {
return '/participant/' + row['related.id'];
},
possibleObjects: [],
nameToShowInSelection: (participant) => {
return (
(participant.contactInformation.person.firstName || '') +
' ' +
(participant.contactInformation.person.name || '') +
' ' +
(participant.contactInformation.email || '') +
' ' +
(participant.contactInformation.phone || '') +
' ' +
(participant.contactInformation.note || '')
);
},
propertyPrefixToOverwrite: 'related',
currentlySelectedObjectId: (provider) => {
return provider['related.id'];
},
propertyNameOfReferenceId: 'relatedId',
},
{
dataPath: 'cargoBike.name',
translation: 'Lastenrad',
link: (element) => {
return '/bike/' + element['cargoBike.id'];
},
possibleObjects: [],
nameToShowInSelection: (bike) => bike.name,
propertyPrefixToOverwrite: 'cargoBike',
currentlySelectedObjectId: (timeFrame) => {
return timeFrame['cargoBike.id'];
},
propertyNameOfReferenceId: 'cargoBikeId',
},
{ dataPath: 'description', translation: 'Beschreibung' },
{ dataPath: 'remark', translation: 'Anmerkung' },
{ dataPath: 'documents', translation: 'Dokumente' },
];
dataService: any;
tableDataGQLType: string = 'BikeEvent';
tableDataGQLCreateInputType: string = 'BikeEventCreateInput';
tableDataGQLUpdateInputType: string = 'BikeEventUpdateInput';
headline = 'Lastenradevent';
headlineIconName = 'event';
loadingRowIds: string[] = [];
constructor(
private participantsService: ParticipantsService,
private bikeEventsService: BikeEventsService,
private bikeEventTypessService: BikeEventTypesService,
private bikesService: BikesService,
) {
this.participantsService.loadTableData();
this.participantsService.tableData.subscribe((data) => {
this.columnInfo.find(
(column) => column.propertyPrefixToOverwrite === 'responsible'
).possibleObjects = data;
this.columnInfo.find(
(column) => column.propertyPrefixToOverwrite === 'related'
).possibleObjects = data;
});
this.bikesService.loadTableData();
this.bikesService.tableData.subscribe((data) => {
this.columnInfo.find(
(column) => column.propertyPrefixToOverwrite === 'cargoBike'
).possibleObjects = data;
});
this.bikeEventTypessService.loadTableData();
this.bikeEventTypessService.tableData.subscribe((data) => {
this.columnInfo.find(
(column) => column.propertyPrefixToOverwrite === 'bikeEventType'
).possibleObjects = data;
});
}
ngOnInit() {
this.dataService = this.bikeEventsService;
}
create(object: { currentId: string; row: any }) {
this.bikeEventsService.createBikeEvent(object.currentId, {
bikeEvent: object.row,
});
}
lock(row: any) {
this.bikeEventsService.lockBikeEvent({ id: row.id });
}
save(row: any) {
this.bikeEventsService.updateBikeEvent({ bikeEvent: row });
}
cancel(row: any) {
this.bikeEventsService.unlockBikeEvent({ id: row.id });
}
delete(row: any) {
this.bikeEventsService.deleteBikeEvent({ id: row.id });
}
}

@ -1 +1,14 @@
<p>engagement-types works!</p>
<app-table
[headline]="headline"
[headlineIconName]="headlineIconName"
[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>

@ -1,15 +1,55 @@
import { Component, OnInit } from '@angular/core';
import { EngagementTypesService } from 'src/app/services/engagementTypes.service';
@Component({
selector: 'app-engagement-types',
templateUrl: './engagement-types.component.html',
styleUrls: ['./engagement-types.component.scss']
styleUrls: ['./engagement-types.component.scss'],
})
export class EngagementTypesComponent implements OnInit {
columnInfo = [
{
dataPath: 'name',
translation: 'Name',
},
{ dataPath: 'description', translation: 'Beschreibung' },
];
constructor() { }
dataService: any;
ngOnInit(): void {
tableDataGQLType: string = 'EngagementType';
tableDataGQLCreateInputType: string = 'EngagementTypeCreateInput';
tableDataGQLUpdateInputType: string = 'EngagementTypeUpdateInput';
headline = 'Engagementtypen';
headlineIconName = 'track_changes';
loadingRowIds: string[] = [];
constructor(private engagementTypesService: EngagementTypesService) {}
ngOnInit() {
this.dataService = this.engagementTypesService;
}
create(object: { currentId: string; row: any }) {
this.engagementTypesService.create(object.currentId, {
engagementType: object.row,
});
}
lock(row: any) {
this.engagementTypesService.lock({ id: row.id });
}
save(row: any) {
this.engagementTypesService.update({ engagementType: row });
}
cancel(row: any) {
this.engagementTypesService.unlock({ id: row.id });
}
delete(row: any) {
this.engagementTypesService.delete({ id: row.id });
}
}

@ -0,0 +1,14 @@
<app-table
[headline]="headline"
[headlineIconName]="headlineIconName"
[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,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { EngagementsComponent } from './engagements.component';
describe('EngagementsComponent', () => {
let component: EngagementsComponent;
let fixture: ComponentFixture<EngagementsComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ EngagementsComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(EngagementsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

@ -0,0 +1,148 @@
import { Component, OnInit } from '@angular/core';
import { BikesService } from 'src/app/services/bikes.service';
import { EngagementsService } from 'src/app/services/engagement.service';
import { EngagementTypesService } from 'src/app/services/engagementTypes.service';
import { ParticipantsService } from 'src/app/services/participants.service';
@Component({
selector: 'app-engagements',
templateUrl: './engagements.component.html',
styleUrls: ['./engagements.component.scss'],
})
export class EngagementsComponent implements OnInit {
columnInfo = [
{
dataPath: 'engagementType.name',
translation: 'Engagementtyp',
},
{
dataPath: 'engagementType.description',
translation: 'Engagementtyp Erklärung',
possibleObjects: [],
nameToShowInSelection: (engagementType) => {
return (
(engagementType.name || '') +
' (' +
(engagementType.description || 'keine Erklärung') + ')'
);
},
propertyPrefixToOverwrite: 'engagementType',
currentlySelectedObjectId: (provider) => {
return provider['engagementType.id'];
},
propertyNameOfReferenceId: 'engagementTypeId',
},
{ dataPath: 'dateRange', translation: 'Zeitraum' },
{
dataPath: 'participant.contactInformation.person.firstName',
translation: 'Aktiver Vorname',
link: (row: any) => {
return '/participant/' + row['participant.id'];
},
},
{
dataPath: 'participant.contactInformation.person.name',
translation: 'Aktiver Nachname',
link: (row: any) => {
return '/participant/' + row['participant.id'];
},
possibleObjects: [],
nameToShowInSelection: (participant) => {
return (
(participant.contactInformation.person.firstName || '') +
' ' +
(participant.contactInformation.person.name || '') +
' ' +
(participant.contactInformation.email || '') +
' ' +
(participant.contactInformation.phone || '') +
' ' +
(participant.contactInformation.note || '')
);
},
propertyPrefixToOverwrite: 'participant',
currentlySelectedObjectId: (provider) => {
return provider['participant.id'];
},
propertyNameOfReferenceId: 'participantId',
},
{
dataPath: 'cargoBike.name',
translation: 'Lastenrad',
link: (element) => {
return '/bike/' + element['cargoBike.id'];
},
possibleObjects: [],
nameToShowInSelection: (bike) => bike.name,
propertyPrefixToOverwrite: 'cargoBike',
currentlySelectedObjectId: (timeFrame) => {
return timeFrame['cargoBike.id'];
},
propertyNameOfReferenceId: 'cargoBikeId'
},
];
dataService: any;
tableDataGQLType: string = 'Engagement';
tableDataGQLCreateInputType: string = 'EngagementCreateInput';
tableDataGQLUpdateInputType: string = 'EngagementUpdateInput';
headline = 'Engagements';
headlineIconName = 'update';
loadingRowIds: string[] = [];
constructor(
private engagementsService: EngagementsService,
private participantsService: ParticipantsService,
private bikesService: BikesService,
private engagementTypesService: EngagementTypesService,
) {
this.participantsService.loadTableData();
this.participantsService.tableData.subscribe((data) => {
this.columnInfo.find(
(column) => column.propertyPrefixToOverwrite === 'participant'
).possibleObjects = data;
});
this.bikesService.loadTableData();
this.bikesService.tableData.subscribe((data) => {
this.columnInfo.find(
(column) => column.propertyPrefixToOverwrite === 'cargoBike'
).possibleObjects = data;
});
this.engagementTypesService.loadTableData();
this.engagementTypesService.tableData.subscribe((data) => {
this.columnInfo.find(
(column) => column.propertyPrefixToOverwrite === 'engagementType'
).possibleObjects = data;
});
}
ngOnInit() {
this.dataService = this.engagementsService;
}
create(object: { currentId: string; row: any }) {
this.engagementsService.create(object.currentId, {
engagement: object.row,
});
}
lock(row: any) {
this.engagementsService.lock({ id: row.id });
}
save(row: any) {
this.engagementsService.update({ engagement: row });
}
cancel(row: any) {
this.engagementsService.unlock({ id: row.id });
}
delete(row: any) {
this.engagementsService.delete({ id: row.id });
}
}

@ -21,7 +21,7 @@ export class OrganisationsComponent implements OnInit {
{ dataPath: 'address.zip', translation: 'Postleitzahl' },
{ dataPath: 'associationNo', translation: 'Vereinsnummer' },
{ dataPath: 'registeredAt', translation: 'Eingetragen seit' },
{ dataPath: 'registeredAt', translation: 'Registergericht' },
{
dataPath: 'contactInformation.person.firstName',

@ -1 +1,14 @@
<p>participants works!</p>
<app-table
[headline]="headline"
[headlineIconName]="headlineIconName"
[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>

@ -1,15 +1,127 @@
import { Component, OnInit } from '@angular/core';
import { ContactInformationService } from 'src/app/services/contactInformation.service';
import { ParticipantsService } from 'src/app/services/participants.service';
@Component({
selector: 'app-participants',
templateUrl: './participants.component.html',
styleUrls: ['./participants.component.scss']
styleUrls: ['./participants.component.scss'],
})
export class ParticipantsComponent implements OnInit {
columnInfo = [
{
dataPath: 'contactInformation.person.firstName',
translation: 'Vorname',
sticky: true,
link: (row: any) => {
return '/person/' + row['contactInformation.person.id'];
},
},
{
dataPath: 'contactInformation.person.name',
translation: 'Nachname',
sticky: true,
link: (row: any) => {
return '/person/' + row['contactInformation.person.id'];
},
possibleObjects: [],
nameToShowInSelection: (contact) => {
return (
(contact.person.firstName || '') +
' ' +
(contact.person.name || '') +
' ' +
(contact.email || '') +
' ' +
(contact.phone || '') +
' ' +
(contact.note || '')
);
},
propertyPrefixToOverwrite: 'contactInformation',
currentlySelectedObjectId: (participant) => {
return participant['contactInformation.id'];
},
propertyNameOfReferenceId: 'contactInformationId',
},
{ dataPath: 'dateRange', translation: 'Zeitraum' },
constructor() { }
{
dataPath: 'contactInformation.phone',
translation: 'Telefonnummer',
},
{
dataPath: 'contactInformation.phone2',
translation: 'Telefonnummer 2',
},
{ dataPath: 'contactInformation.email', translation: 'Email' },
{ dataPath: 'contactInformation.email2', translation: 'Email 2' },
ngOnInit(): void {
{ dataPath: 'usernamefLotte', translation: 'User fLotte' },
{ dataPath: 'usernameSlack', translation: 'User Slack' },
{ dataPath: 'memberADFC', translation: 'Mitglied ADFC' },
{
dataPath: 'locationZIPs',
translation: 'Einsatz in PLZ',
},
{
dataPath: 'memberCoreTeam',
translation: 'Teil des Kernteams',
},
{
dataPath: 'distributedActiveBikeParte',
translation: 'Verteiler aktive Radpat*innen',
},
];
dataService: any;
tableDataGQLType: string = 'Participant';
tableDataGQLCreateInputType: string = 'ParticipantCreateInput';
tableDataGQLUpdateInputType: string = 'ParticipantUpdateInput';
headline = 'Aktive';
headlineIconName = 'directions_run';
loadingRowIds: string[] = [];
constructor(
private participantsService: ParticipantsService,
private contactInformationService: ContactInformationService
) {
this.contactInformationService.loadTableData();
this.contactInformationService.tableData.subscribe((data) => {
this.columnInfo.find(
(column) => column.propertyPrefixToOverwrite === 'contactInformation'
).possibleObjects = data;
});
}
ngOnInit() {
this.dataService = this.participantsService;
}
create(object: { currentId: string; row: any }) {
this.participantsService.createParticipant(object.currentId, {
participant: object.row,
});
}
lock(row: any) {
this.participantsService.lockParticipant({ id: row.id });
}
save(row: any) {
this.participantsService.updateParticipant({ participant: row });
}
cancel(row: any) {
this.participantsService.unlockParticipant({ id: row.id });
}
delete(row: any) {
this.participantsService.deleteParticipant({ id: row.id });
}
}

@ -0,0 +1,14 @@
<app-table
[headline]="headline"
[headlineIconName]="headlineIconName"
[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,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { WorkshopTypesComponent } from './workshop-types.component';
describe('WorkshopTypesComponent', () => {
let component: WorkshopTypesComponent;
let fixture: ComponentFixture<WorkshopTypesComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ WorkshopTypesComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(WorkshopTypesComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

@ -0,0 +1,54 @@
import { Component, OnInit } from '@angular/core';
import { WorkshopTypesService } from 'src/app/services/workshopTypes.service';
@Component({
selector: 'app-workshop-types',
templateUrl: './workshop-types.component.html',
styleUrls: ['./workshop-types.component.scss']
})
export class WorkshopTypesComponent implements OnInit {
columnInfo = [
{
dataPath: 'name',
translation: 'Name',
},
];
dataService: any;
tableDataGQLType: string = 'WorkshopType';
tableDataGQLCreateInputType: string = 'WorkshopTypeCreateInput';
tableDataGQLUpdateInputType: string = 'WorkshopTypeUpdateInput';
headline = 'Workshoptypen';
headlineIconName = 'multiline_chart';
loadingRowIds: string[] = [];
constructor(private workshopTypesService: WorkshopTypesService) {}
ngOnInit() {
this.dataService = this.workshopTypesService;
}
create(object: { currentId: string; row: any }) {
this.workshopTypesService.create(object.currentId, {
workshopType: object.row,
});
}
lock(row: any) {
this.workshopTypesService.lock({ id: row.id });
}
save(row: any) {
this.workshopTypesService.update({ workshopType: row });
}
cancel(row: any) {
this.workshopTypesService.unlock({ id: row.id });
}
delete(row: any) {
this.workshopTypesService.delete({ id: row.id });
}
}

@ -1 +1,14 @@
<p>workshops works!</p>
<app-table
[headline]="headline"
[headlineIconName]="headlineIconName"
[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>

@ -1,15 +1,168 @@
import { Component, OnInit } from '@angular/core';
import { ParticipantsService } from 'src/app/services/participants.service';
import { WorkshopTypesService } from 'src/app/services/workshopTypes.service';
import { WorkshopsService } from 'src/app/services/workshop.service';
@Component({
selector: 'app-workshops',
templateUrl: './workshops.component.html',
styleUrls: ['./workshops.component.scss']
styleUrls: ['./workshops.component.scss'],
})
export class WorkshopsComponent implements OnInit {
columnInfo = [
{
dataPath: 'title',
translation: 'Workshopname',
},
{
dataPath: 'description',
translation: 'Details',
},
{
dataPath: 'workshopType.name',
translation: 'Workshoptyp',
possibleObjects: [],
nameToShowInSelection: (workshopType) => {
return workshopType.name;
},
propertyPrefixToOverwrite: 'workshopType',
currentlySelectedObjectId: (provider) => {
return provider['workshopType.id'];
},
propertyNameOfReferenceId: 'workshopTypeId',
},
{
dataPath: 'date',
translation: 'Datum',
},
constructor() { }
{
dataPath: 'trainer1.contactInformation.person.firstName',
translation: 'Trainer 1 Vorname',
link: (row: any) => {
return '/participant/' + row['trainer1.id'];
},
},
{
dataPath: 'trainer1.contactInformation.person.name',
translation: 'Trainer 1 Nachname',
link: (row: any) => {
return '/participant/' + row['trainer1.id'];
},
possibleObjects: [],
nameToShowInSelection: (participant) => {
return (
(participant.contactInformation.person.firstName || '') +
' ' +
(participant.contactInformation.person.name || '') +
' ' +
(participant.contactInformation.email || '') +
' ' +
(participant.contactInformation.phone || '') +
' ' +
(participant.contactInformation.note || '')
);
},
propertyPrefixToOverwrite: 'trainer1',
currentlySelectedObjectId: (provider) => {
return provider['trainer1.id'];
},
propertyNameOfReferenceId: 'trainer1Id',
},
ngOnInit(): void {
{
dataPath: 'trainer2.contactInformation.person.firstName',
translation: 'Trainer 2 Vorname',
link: (row: any) => {
return '/participant/' + row['trainer2.id'];
},
},
{
dataPath: 'trainer2.contactInformation.person.name',
translation: 'Trainer 2 Nachname',
link: (row: any) => {
return '/participant/' + row['trainer2.id'];
},
possibleObjects: [],
nameToShowInSelection: (participant) => {
return (
(participant.contactInformation.person.firstName || '') +
' ' +
(participant.contactInformation.person.name || '') +
' ' +
(participant.contactInformation.email || '') +
' ' +
(participant.contactInformation.phone || '') +
' ' +
(participant.contactInformation.note || '')
);
},
propertyPrefixToOverwrite: 'trainer2',
currentlySelectedObjectId: (provider) => {
return provider['trainer2.id'];
},
propertyNameOfReferenceId: 'trainer2Id',
},
];
dataService: any;
tableDataGQLType: string = 'Workshop';
tableDataGQLCreateInputType: string = 'WorkshopCreateInput';
tableDataGQLUpdateInputType: string = 'WorkshopUpdateInput';
headline = 'Workshops';
headlineIconName = 'school';
loadingRowIds: string[] = [];
constructor(
private participantsService: ParticipantsService,
private workshopTypesService: WorkshopTypesService,
private workshopsService: WorkshopsService,
) {
this.participantsService.loadTableData();
this.participantsService.tableData.subscribe((data) => {
this.columnInfo.find(
(column) => column.propertyPrefixToOverwrite === 'trainer1'
).possibleObjects = data;
this.columnInfo.find(
(column) => column.propertyPrefixToOverwrite === 'trainer2'
).possibleObjects = data;
});
this.workshopTypesService.loadTableData();
this.workshopTypesService.tableData.subscribe((data) => {
this.columnInfo.find(
(column) => column.propertyPrefixToOverwrite === 'workshopType'
).possibleObjects = data;
});
}
ngOnInit() {
this.dataService = this.workshopsService;
}
create(object: { currentId: string; row: any }) {
this.workshopsService.createWorkshop(object.currentId, {
workshop: object.row,
});
}
lock(row: any) {
this.workshopsService.lockWorkshop({ id: row.id });
}
save(row: any) {
this.workshopsService.updateWorkshop({ workshop: row });
}
cancel(row: any) {
this.workshopsService.unlockWorkshop({ id: row.id });
}
delete(row: any) {
this.workshopsService.deleteWorkshop({ id: row.id });
}
}

@ -0,0 +1,160 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject, Subject } from 'rxjs';
import {
GetBikeEventsGQL,
ReloadBikeEventByIdGQL,
ReloadBikeEventByIdQueryVariables,
UpdateBikeEventGQL,
UpdateBikeEventMutationVariables,
LockBikeEventGQL,
LockBikeEventMutationVariables,
UnlockBikeEventGQL,
UnlockBikeEventMutationVariables,
CreateBikeEventGQL,
CreateBikeEventMutationVariables,
DeleteBikeEventGQL,
DeleteBikeEventMutationVariables,
GetBikeEventByIdGQL,
GetBikeEventByIdQueryVariables,
} from '../../generated/graphql';
@Injectable({
providedIn: 'root',
})
export class BikeEventsService {
/** BikeEvents Array */
tableData: BehaviorSubject<any[]> = new BehaviorSubject(null);
loadingRowIds: BehaviorSubject<string[]> = new BehaviorSubject([]);
successfullyCreatedRowWithId: Subject<string> = new Subject();
pageData: BehaviorSubject<any> = new BehaviorSubject(null);
isLoadingPageData: BehaviorSubject<boolean> = new BehaviorSubject(false);
constructor(
private getBikeEventsGQL: GetBikeEventsGQL,
private getBikeEventByIdGQL: GetBikeEventByIdGQL,
private reloadBikeEventByIdGQL: ReloadBikeEventByIdGQL,
private updateBikeEventGQL: UpdateBikeEventGQL,
private lockBikeEventGQL: LockBikeEventGQL,
private unlockBikeEventGQL: UnlockBikeEventGQL,
private createBikeEventGQL: CreateBikeEventGQL,
private deleteBikeEventGQL: DeleteBikeEventGQL
) {}
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.getBikeEventsGQL.fetch().subscribe((result) => {
this.tableData.next(result.data?.bikeEvents);
});
}
loadPageData(variables: GetBikeEventByIdQueryVariables) {
this.pageData.next(null);
this.isLoadingPageData.next(true);
this.getBikeEventByIdGQL
.fetch(variables)
.subscribe((result) => {
this.pageData.next(result.data.bikeEventById);
})
.add(() => {
this.isLoadingPageData.next(false);
});
}
reloadBikeEvent(variables: ReloadBikeEventByIdQueryVariables) {
this.addLoadingRowId(variables.id);
this.reloadBikeEventByIdGQL
.fetch(variables)
.subscribe((result) => {
this.updateDataRowFromResponse(result.data.bikeEventById);
})
.add(() => {
this.removeLoadingRowId(variables.id);
});
}
createBikeEvent(currentId: string, variables: CreateBikeEventMutationVariables) {
this.createBikeEventGQL.mutate(variables).subscribe((result) => {
const newBikeEvent = result.data.createBikeEvent;
this.tableData.next([newBikeEvent, ...this.tableData.value]);
this.successfullyCreatedRowWithId.next(currentId);
});
}
updateBikeEvent(variables: UpdateBikeEventMutationVariables) {
this.addLoadingRowId(variables.bikeEvent.id);
this.updateBikeEventGQL
.mutate(variables)
.subscribe((result) => {
this.updateDataRowFromResponse(result.data.updateBikeEvent);
})
.add(() => {
this.removeLoadingRowId(variables.bikeEvent.id);
});
}
lockBikeEvent(variables: LockBikeEventMutationVariables) {
this.addLoadingRowId(variables.id);
this.lockBikeEventGQL
.mutate(variables)
.subscribe((result) => {
this.updateDataRowFromResponse(result.data.lockBikeEvent);
})
.add(() => {
this.removeLoadingRowId(variables.id);
});
}
unlockBikeEvent(variables: UnlockBikeEventMutationVariables) {
this.addLoadingRowId(variables.id);
this.unlockBikeEventGQL
.mutate(variables)
.subscribe((result) => {
this.updateDataRowFromResponse(result.data.unlockBikeEvent);
})
.add(() => {
this.removeLoadingRowId(variables.id);
});
}
deleteBikeEvent(variables: DeleteBikeEventMutationVariables) {
this.addLoadingRowId(variables.id);
this.deleteBikeEventGQL
.mutate(variables)
.subscribe((result) => {
if (result.data) {
this.tableData.next(
[...this.tableData.value].filter((bikeEvent) => bikeEvent.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);
}
if (rowFromResponse.id === this.pageData?.value?.id) {
this.pageData.next(rowFromResponse);
}
}
}

@ -0,0 +1,125 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject, Subject } from 'rxjs';
import {
GetBikeEventTypesGQL,
CreateBikeEventTypeGQL,
CreateBikeEventTypeMutationVariables,
UpdateBikeEventTypeGQL,
UpdateBikeEventTypeMutationVariables,
LockBikeEventTypeGQL,
LockBikeEventTypeMutationVariables,
UnlockBikeEventTypeGQL,
UnlockBikeEventTypeMutationVariables,
DeleteBikeEventTypeGQL,
DeleteBikeEventTypeMutationVariables,
} from '../../generated/graphql';
@Injectable({
providedIn: 'root',
})
export class BikeEventTypesService {
/** BikeEventTypes 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 getBikeEventTypesGQL: GetBikeEventTypesGQL,
private createBikeEventTypeGQL: CreateBikeEventTypeGQL,
private updateBikeEventTypeGQL: UpdateBikeEventTypeGQL,
private lockBikeEventTypeGQL: LockBikeEventTypeGQL,
private unlockBikeEventTypeGQL: UnlockBikeEventTypeGQL,
private deleteBikeEventTypeGQL: DeleteBikeEventTypeGQL
) {}
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.getBikeEventTypesGQL.fetch().subscribe((result) => {
this.tableData.next(result.data.bikeEventTypes);
});
}
create(currentId: string, variables: CreateBikeEventTypeMutationVariables) {
this.createBikeEventTypeGQL.mutate(variables).subscribe((result) => {
const newRow = result.data.createBikeEventType;
this.tableData.next([newRow, ...this.tableData.value]);
this.successfullyCreatedRowWithId.next(currentId);
});
}
update(variables: UpdateBikeEventTypeMutationVariables) {
this.addLoadingRowId(variables.bikeEventType.id);
this.updateBikeEventTypeGQL
.mutate(variables)
.subscribe((result) => {
this.updateDataRowFromResponse(result.data.updateBikeEventType);
})
.add(() => {
this.removeLoadingRowId(variables.bikeEventType.id);
});
}
lock(variables: LockBikeEventTypeMutationVariables) {
this.addLoadingRowId(variables.id);
this.lockBikeEventTypeGQL
.mutate(variables)
.subscribe((result) => {
this.updateDataRowFromResponse(result.data.lockBikeEventType);
})
.add(() => {
this.removeLoadingRowId(variables.id);
});
}
unlock(variables: UnlockBikeEventTypeMutationVariables) {
this.addLoadingRowId(variables.id);
this.unlockBikeEventTypeGQL
.mutate(variables)
.subscribe((result) => {
this.updateDataRowFromResponse(result.data.unlockBikeEventType);
})
.add(() => {
this.removeLoadingRowId(variables.id);
});
}
delete(variables: DeleteBikeEventTypeMutationVariables) {
this.addLoadingRowId(variables.id);
this.deleteBikeEventTypeGQL
.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);
}
}
}

@ -0,0 +1,125 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject, Subject } from 'rxjs';
import {
GetEngagementsGQL,
CreateEngagementGQL,
CreateEngagementMutationVariables,
UpdateEngagementGQL,
UpdateEngagementMutationVariables,
LockEngagementGQL,
LockEngagementMutationVariables,
UnlockEngagementGQL,
UnlockEngagementMutationVariables,
DeleteEngagementGQL,
DeleteEngagementMutationVariables,
} from '../../generated/graphql';
@Injectable({
providedIn: 'root',
})
export class EngagementsService {
/** Engagements 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 getEngagementsGQL: GetEngagementsGQL,
private createEngagementGQL: CreateEngagementGQL,
private updateEngagementGQL: UpdateEngagementGQL,
private lockEngagementGQL: LockEngagementGQL,
private unlockEngagementGQL: UnlockEngagementGQL,
private deleteEngagementGQL: DeleteEngagementGQL
) {}
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.getEngagementsGQL.fetch().subscribe((result) => {
this.tableData.next(result.data.engagements);
});
}
create(currentId: string, variables: CreateEngagementMutationVariables) {
this.createEngagementGQL.mutate(variables).subscribe((result) => {
const newRow = result.data.createEngagement;
this.tableData.next([newRow, ...this.tableData.value]);
this.successfullyCreatedRowWithId.next(currentId);
});
}
update(variables: UpdateEngagementMutationVariables) {
this.addLoadingRowId(variables.engagement.id);
this.updateEngagementGQL
.mutate(variables)
.subscribe((result) => {
this.updateDataRowFromResponse(result.data.updateEngagement);
})
.add(() => {
this.removeLoadingRowId(variables.engagement.id);
});
}
lock(variables: LockEngagementMutationVariables) {
this.addLoadingRowId(variables.id);
this.lockEngagementGQL
.mutate(variables)
.subscribe((result) => {
this.updateDataRowFromResponse(result.data.lockEngagement);
})
.add(() => {
this.removeLoadingRowId(variables.id);
});
}
unlock(variables: UnlockEngagementMutationVariables) {
this.addLoadingRowId(variables.id);
this.unlockEngagementGQL
.mutate(variables)
.subscribe((result) => {
this.updateDataRowFromResponse(result.data.unlockEngagement);
})
.add(() => {
this.removeLoadingRowId(variables.id);
});
}
delete(variables: DeleteEngagementMutationVariables) {
this.addLoadingRowId(variables.id);
this.deleteEngagementGQL
.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);
}
}
}

@ -0,0 +1,125 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject, Subject } from 'rxjs';
import {
GetEngagementTypesGQL,
CreateEngagementTypeGQL,
CreateEngagementTypeMutationVariables,
UpdateEngagementTypeGQL,
UpdateEngagementTypeMutationVariables,
LockEngagementTypeGQL,
LockEngagementTypeMutationVariables,
UnlockEngagementTypeGQL,
UnlockEngagementTypeMutationVariables,
DeleteEngagementTypeGQL,
DeleteEngagementTypeMutationVariables,
} from '../../generated/graphql';
@Injectable({
providedIn: 'root',
})
export class EngagementTypesService {
/** EngagementTypes 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 getEngagementTypesGQL: GetEngagementTypesGQL,
private createEngagementTypeGQL: CreateEngagementTypeGQL,
private updateEngagementTypeGQL: UpdateEngagementTypeGQL,
private lockEngagementTypeGQL: LockEngagementTypeGQL,
private unlockEngagementTypeGQL: UnlockEngagementTypeGQL,
private deleteEngagementTypeGQL: DeleteEngagementTypeGQL
) {}
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.getEngagementTypesGQL.fetch().subscribe((result) => {
this.tableData.next(result.data.engagementTypes);
});
}
create(currentId: string, variables: CreateEngagementTypeMutationVariables) {
this.createEngagementTypeGQL.mutate(variables).subscribe((result) => {
const newRow = result.data.createEngagementType;
this.tableData.next([newRow, ...this.tableData.value]);
this.successfullyCreatedRowWithId.next(currentId);
});
}
update(variables: UpdateEngagementTypeMutationVariables) {
this.addLoadingRowId(variables.engagementType.id);
this.updateEngagementTypeGQL
.mutate(variables)
.subscribe((result) => {
this.updateDataRowFromResponse(result.data.updateEngagementType);
})
.add(() => {
this.removeLoadingRowId(variables.engagementType.id);
});
}
lock(variables: LockEngagementTypeMutationVariables) {
this.addLoadingRowId(variables.id);
this.lockEngagementTypeGQL
.mutate(variables)
.subscribe((result) => {
this.updateDataRowFromResponse(result.data.lockEngagementType);
})
.add(() => {
this.removeLoadingRowId(variables.id);
});
}
unlock(variables: UnlockEngagementTypeMutationVariables) {
this.addLoadingRowId(variables.id);
this.unlockEngagementTypeGQL
.mutate(variables)
.subscribe((result) => {
this.updateDataRowFromResponse(result.data.unlockEngagementType);
})
.add(() => {
this.removeLoadingRowId(variables.id);
});
}
delete(variables: DeleteEngagementTypeMutationVariables) {
this.addLoadingRowId(variables.id);
this.deleteEngagementTypeGQL
.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,9 +1,160 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject, Subject } from 'rxjs';
import {
GetParticipantsGQL,
ReloadParticipantByIdGQL,
ReloadParticipantByIdQueryVariables,
UpdateParticipantGQL,
UpdateParticipantMutationVariables,
LockParticipantGQL,
LockParticipantMutationVariables,
UnlockParticipantGQL,
UnlockParticipantMutationVariables,
CreateParticipantGQL,
CreateParticipantMutationVariables,
DeleteParticipantGQL,
DeleteParticipantMutationVariables,
GetParticipantByIdGQL,
GetParticipantByIdQueryVariables,
} from '../../generated/graphql';
@Injectable({
providedIn: 'root'
providedIn: 'root',
})
export class ParticipantsService {
/** Participants Array */
tableData: BehaviorSubject<any[]> = new BehaviorSubject(null);
loadingRowIds: BehaviorSubject<string[]> = new BehaviorSubject([]);
successfullyCreatedRowWithId: Subject<string> = new Subject();
pageData: BehaviorSubject<any> = new BehaviorSubject(null);
isLoadingPageData: BehaviorSubject<boolean> = new BehaviorSubject(false);
constructor() { }
constructor(
private getParticipantsGQL: GetParticipantsGQL,
private getParticipantByIdGQL: GetParticipantByIdGQL,
private reloadParticipantByIdGQL: ReloadParticipantByIdGQL,
private updateParticipantGQL: UpdateParticipantGQL,
private lockParticipantGQL: LockParticipantGQL,
private unlockParticipantGQL: UnlockParticipantGQL,
private createParticipantGQL: CreateParticipantGQL,
private deleteParticipantGQL: DeleteParticipantGQL
) {}
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.getParticipantsGQL.fetch().subscribe((result) => {
this.tableData.next(result.data?.participants);
});
}
loadPageData(variables: GetParticipantByIdQueryVariables) {
this.pageData.next(null);
this.isLoadingPageData.next(true);
this.getParticipantByIdGQL
.fetch(variables)
.subscribe((result) => {
this.pageData.next(result.data.participantById);
})
.add(() => {
this.isLoadingPageData.next(false);
});
}
reloadParticipant(variables: ReloadParticipantByIdQueryVariables) {
this.addLoadingRowId(variables.id);
this.reloadParticipantByIdGQL
.fetch(variables)
.subscribe((result) => {
this.updateDataRowFromResponse(result.data.participantById);
})
.add(() => {
this.removeLoadingRowId(variables.id);
});
}
createParticipant(currentId: string, variables: CreateParticipantMutationVariables) {
this.createParticipantGQL.mutate(variables).subscribe((result) => {
const newParticipant = result.data.createParticipant;
this.tableData.next([newParticipant, ...this.tableData.value]);
this.successfullyCreatedRowWithId.next(currentId);
});
}
updateParticipant(variables: UpdateParticipantMutationVariables) {
this.addLoadingRowId(variables.participant.id);
this.updateParticipantGQL
.mutate(variables)
.subscribe((result) => {
this.updateDataRowFromResponse(result.data.updateParticipant);
})
.add(() => {
this.removeLoadingRowId(variables.participant.id);
});
}
lockParticipant(variables: LockParticipantMutationVariables) {
this.addLoadingRowId(variables.id);
this.lockParticipantGQL
.mutate(variables)
.subscribe((result) => {
this.updateDataRowFromResponse(result.data.lockParticipant);
})
.add(() => {
this.removeLoadingRowId(variables.id);
});
}
unlockParticipant(variables: UnlockParticipantMutationVariables) {
this.addLoadingRowId(variables.id);
this.unlockParticipantGQL
.mutate(variables)
.subscribe((result) => {
this.updateDataRowFromResponse(result.data.unlockParticipant);
})
.add(() => {
this.removeLoadingRowId(variables.id);
});
}
deleteParticipant(variables: DeleteParticipantMutationVariables) {
this.addLoadingRowId(variables.id);
this.deleteParticipantGQL
.mutate(variables)
.subscribe((result) => {
if (result.data) {
this.tableData.next(
[...this.tableData.value].filter((participant) => participant.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);
}
if (rowFromResponse.id === this.pageData?.value?.id) {
this.pageData.next(rowFromResponse);
}
}
}

@ -5,41 +5,6 @@ import jsonSchema from 'src/generated/graphql.schema.json';
providedIn: 'root',
})
export class SchemaService {
/** expects startingObject and variablePath and returns its type e.g. cargoBike, security.name -> returns the type of the name variable */
/*getPropertyTypeFromSchema(
startingObjectName: string,
variable: string
): string {
const variablePath = variable.split('.');
const types = jsonSchema.__schema.types;
const startingObject = types.find(
(type) => type.name === startingObjectName
);
const field = startingObject.fields.find(
(field) => field.name === variablePath[0]
);
const type = field.type.name || field.type.ofType.name;
if (variablePath.length === 1) {
if (
field.type.kind === 'ENUM' ||
(field.type.kind === 'NON_NULL' && field.type.ofType.kind === 'ENUM')
) {
return (
'Enum//' +
this.getEnumValuesFromSchema(
field.type.name || field.type.ofType.name
).join('//')
);
}
return type;
} else {
return this.getPropertyTypeFromSchema(
type,
variablePath.slice(1).join('.')
);
}
}*/
getEnumValuesFromSchema(typeName: string): string[] {
const types = jsonSchema.__schema.types;
const type = types.find((type) => type.name === typeName);
@ -50,22 +15,42 @@ export class SchemaService {
getTypeInformation(
startingObjectName: string,
variable: string
): { isPartOfType: boolean; type: string; isRequired: boolean } {
): {
isPartOfType: boolean;
type: string;
isRequired: boolean;
isList: boolean;
} {
const variablePath = variable.split('.');
const types = jsonSchema.__schema.types;
const startingObject = types.find(
(type) => type.name === startingObjectName
);
if (!startingObject) {
return { isPartOfType: false, type: '', isRequired: false };
return {
isPartOfType: false,
type: '',
isRequired: false,
isList: false,
};
}
const fields = startingObject.fields || startingObject.inputFields;
if (!fields) {
return { isPartOfType: false, type: '', isRequired: false };
return {
isPartOfType: false,
type: '',
isRequired: false,
isList: false,
};
}
const field = fields.find((field) => field.name === variablePath[0]);
if (!field) {
return { isPartOfType: false, type: '', isRequired: false };
return {
isPartOfType: false,
type: '',
isRequired: false,
isList: false,
};
}
const type = this.getTypeNameFromTypeObject(field.type);
if (variablePath.length === 1) {
@ -82,12 +67,15 @@ export class SchemaService {
field.type.name || field.type.ofType.name
).join('//'),
isRequired: isRequired,
isList: false,
};
} else
return {
isPartOfType: true,
type: type,
isRequired: isRequired,
isList:
field.type?.kind === 'LIST' || field.type?.ofType?.kind === 'LIST',
};
} else {
return this.getTypeInformation(type, variablePath.slice(1).join('.'));
@ -95,12 +83,12 @@ export class SchemaService {
}
private getTypeNameFromTypeObject(typeObject: any) {
let object =typeObject;
let object = typeObject;
while (object.name == null && object.ofType != null) {
object = object.ofType;
}
return object.name;
}
}
filterObject(graphQLTypeName: string, object: object): any {
let filteredObject;

@ -3,23 +3,15 @@ import { HttpClient } from '@angular/common/http';
import { catchError, finalize, map, tap } from 'rxjs/operators';
import { environment } from '../../environments/environment';
import { Observable, BehaviorSubject, of } from 'rxjs';
import { User } from "../models/user";
import { AuthService} from "./auth.service";
import { User } from '../models/user';
import { AuthService } from './auth.service';
import { ObserveOnSubscriber } from 'rxjs/internal/operators/observeOn';
@Injectable({
providedIn: 'root',
})
export class UserService {
constructor(private http: HttpClient, private authService: AuthService) {
}
constructor(private http: HttpClient, private authService: AuthService) {}
public getAllUsers(): Observable<User[]> {
return this.http.get<User[]>(`${environment.authUrl}/users`);
@ -30,15 +22,21 @@ export class UserService {
}
public getUserPermissions(email: string): Observable<any> {
return this.http.get<any>(`${environment.authUrl}/users/${email}/permissions`)
return this.http.get<any>(
`${environment.authUrl}/users/${email}/permissions`
);
}
public updateUser(user: User): Observable<User> {
return this.http.post<User>(`${environment.authUrl}/users/${user.email}/update`, user);
return this.http.post<User>(
`${environment.authUrl}/users/${user.email}/update`,
user
);
}
public deleteUser(email: string): Observable<any> {
return this.http.delete<any>(`${environment.authUrl}/users/` + email + "/delete");
return this.http.delete<any>(
`${environment.authUrl}/users/` + email + '/delete'
);
}
}

@ -0,0 +1,160 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject, Subject } from 'rxjs';
import {
GetWorkshopsGQL,
ReloadWorkshopByIdGQL,
ReloadWorkshopByIdQueryVariables,
UpdateWorkshopGQL,
UpdateWorkshopMutationVariables,
LockWorkshopGQL,
LockWorkshopMutationVariables,
UnlockWorkshopGQL,
UnlockWorkshopMutationVariables,
CreateWorkshopGQL,
CreateWorkshopMutationVariables,
DeleteWorkshopGQL,
DeleteWorkshopMutationVariables,
GetWorkshopByIdGQL,
GetWorkshopByIdQueryVariables,
} from '../../generated/graphql';
@Injectable({
providedIn: 'root',
})
export class WorkshopsService {
/** Workshops Array */
tableData: BehaviorSubject<any[]> = new BehaviorSubject(null);
loadingRowIds: BehaviorSubject<string[]> = new BehaviorSubject([]);
successfullyCreatedRowWithId: Subject<string> = new Subject();
pageData: BehaviorSubject<any> = new BehaviorSubject(null);
isLoadingPageData: BehaviorSubject<boolean> = new BehaviorSubject(false);
constructor(
private getWorkshopsGQL: GetWorkshopsGQL,
private getWorkshopByIdGQL: GetWorkshopByIdGQL,
private reloadWorkshopByIdGQL: ReloadWorkshopByIdGQL,
private updateWorkshopGQL: UpdateWorkshopGQL,
private lockWorkshopGQL: LockWorkshopGQL,
private unlockWorkshopGQL: UnlockWorkshopGQL,
private createWorkshopGQL: CreateWorkshopGQL,
private deleteWorkshopGQL: DeleteWorkshopGQL
) {}
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.getWorkshopsGQL.fetch().subscribe((result) => {
this.tableData.next(result.data?.workshops);
});
}
loadPageData(variables: GetWorkshopByIdQueryVariables) {
this.pageData.next(null);
this.isLoadingPageData.next(true);
this.getWorkshopByIdGQL
.fetch(variables)
.subscribe((result) => {
this.pageData.next(result.data.workshopById);
})
.add(() => {
this.isLoadingPageData.next(false);
});
}
reloadWorkshop(variables: ReloadWorkshopByIdQueryVariables) {
this.addLoadingRowId(variables.id);
this.reloadWorkshopByIdGQL
.fetch(variables)
.subscribe((result) => {
this.updateDataRowFromResponse(result.data.workshopById);
})
.add(() => {
this.removeLoadingRowId(variables.id);
});
}
createWorkshop(currentId: string, variables: CreateWorkshopMutationVariables) {
this.createWorkshopGQL.mutate(variables).subscribe((result) => {
const newWorkshop = result.data.createWorkshop;
this.tableData.next([newWorkshop, ...this.tableData.value]);
this.successfullyCreatedRowWithId.next(currentId);
});
}
updateWorkshop(variables: UpdateWorkshopMutationVariables) {
this.addLoadingRowId(variables.workshop.id);
this.updateWorkshopGQL
.mutate(variables)
.subscribe((result) => {
this.updateDataRowFromResponse(result.data.updateWorkshop);
})
.add(() => {
this.removeLoadingRowId(variables.workshop.id);
});
}
lockWorkshop(variables: LockWorkshopMutationVariables) {
this.addLoadingRowId(variables.id);
this.lockWorkshopGQL
.mutate(variables)
.subscribe((result) => {
this.updateDataRowFromResponse(result.data.lockWorkshop);
})
.add(() => {
this.removeLoadingRowId(variables.id);
});
}
unlockWorkshop(variables: UnlockWorkshopMutationVariables) {
this.addLoadingRowId(variables.id);
this.unlockWorkshopGQL
.mutate(variables)
.subscribe((result) => {
this.updateDataRowFromResponse(result.data.unlockWorkshop);
})
.add(() => {
this.removeLoadingRowId(variables.id);
});
}
deleteWorkshop(variables: DeleteWorkshopMutationVariables) {
this.addLoadingRowId(variables.id);
this.deleteWorkshopGQL
.mutate(variables)
.subscribe((result) => {
if (result.data) {
this.tableData.next(
[...this.tableData.value].filter((workshop) => workshop.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);
}
if (rowFromResponse.id === this.pageData?.value?.id) {
this.pageData.next(rowFromResponse);
}
}
}

@ -0,0 +1,125 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject, Subject } from 'rxjs';
import {
GetWorkshopTypesGQL,
CreateWorkshopTypeGQL,
CreateWorkshopTypeMutationVariables,
UpdateWorkshopTypeGQL,
UpdateWorkshopTypeMutationVariables,
LockWorkshopTypeGQL,
LockWorkshopTypeMutationVariables,
UnlockWorkshopTypeGQL,
UnlockWorkshopTypeMutationVariables,
DeleteWorkshopTypeGQL,
DeleteWorkshopTypeMutationVariables,
} from '../../generated/graphql';
@Injectable({
providedIn: 'root',
})
export class WorkshopTypesService {
/** WorkshopTypes 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 getWorkshopTypesGQL: GetWorkshopTypesGQL,
private createWorkshopTypeGQL: CreateWorkshopTypeGQL,
private updateWorkshopTypeGQL: UpdateWorkshopTypeGQL,
private lockWorkshopTypeGQL: LockWorkshopTypeGQL,
private unlockWorkshopTypeGQL: UnlockWorkshopTypeGQL,
private deleteWorkshopTypeGQL: DeleteWorkshopTypeGQL
) {}
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.getWorkshopTypesGQL.fetch().subscribe((result) => {
this.tableData.next(result.data.workshopTypes);
});
}
create(currentId: string, variables: CreateWorkshopTypeMutationVariables) {
this.createWorkshopTypeGQL.mutate(variables).subscribe((result) => {
const newRow = result.data.createWorkshopType;
this.tableData.next([newRow, ...this.tableData.value]);
this.successfullyCreatedRowWithId.next(currentId);
});
}
update(variables: UpdateWorkshopTypeMutationVariables) {
this.addLoadingRowId(variables.workshopType.id);
this.updateWorkshopTypeGQL
.mutate(variables)
.subscribe((result) => {
this.updateDataRowFromResponse(result.data.updateWorkshopType);
})
.add(() => {
this.removeLoadingRowId(variables.workshopType.id);
});
}
lock(variables: LockWorkshopTypeMutationVariables) {
this.addLoadingRowId(variables.id);
this.lockWorkshopTypeGQL
.mutate(variables)
.subscribe((result) => {
this.updateDataRowFromResponse(result.data.lockWorkshopType);
})
.add(() => {
this.removeLoadingRowId(variables.id);
});
}
unlock(variables: UnlockWorkshopTypeMutationVariables) {
this.addLoadingRowId(variables.id);
this.unlockWorkshopTypeGQL
.mutate(variables)
.subscribe((result) => {
this.updateDataRowFromResponse(result.data.unlockWorkshopType);
})
.add(() => {
this.removeLoadingRowId(variables.id);
});
}
delete(variables: DeleteWorkshopTypeMutationVariables) {
this.addLoadingRowId(variables.id);
this.deleteWorkshopTypeGQL
.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);
}
}
}

@ -49,6 +49,16 @@
"enumValues": null,
"possibleTypes": null
},
{
"kind": "SCALAR",
"name": "Link",
"description": null,
"fields": null,
"inputFields": null,
"interfaces": null,
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "CargoBike",
@ -2487,7 +2497,7 @@
},
{
"name": "distributedActiveBikeParte",
"description": "Note the kommentierte Infodaten Tabelle.\nThis value is calculated form other values.\nIt is true, if the person is not on the black list and not retired\nand is either Mentor dt. Pate or Partner Mentor dt. Partnerpate for at least one bike.",
"description": "Note the kommentierte Infodaten Tabelle.\nThis value is calculated form other values.\nIt is true, if the person is not on the black list and not retired\nand is either Mentor dt. Pate or Partner Mentor dt. Partnerpate for at least one bike.\nNote: this will always be false for the moment.",
"args": [],
"type": {
"kind": "NON_NULL",
@ -4581,7 +4591,7 @@
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"name": "Link",
"ofType": null
}
}
@ -4750,7 +4760,7 @@
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"name": "Link",
"ofType": null
}
},
@ -4859,7 +4869,7 @@
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"name": "Link",
"ofType": null
}
},
@ -7460,6 +7470,33 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "copyCargoBikeById",
"description": "copies cargoBike, the id of the copy needs to be delted by the front end. This function will not create a new entry in the data base",
"args": [
{
"name": "id",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
}
},
"defaultValue": null
}
],
"type": {
"kind": "OBJECT",
"name": "CargoBike",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "cargoBikes",
"description": "Returns cargoBikes ordered by name ascending. If offset or limit is not provided, both values are ignored.",
@ -8479,7 +8516,7 @@
"deprecationReason": null
},
{
"name": "bikeEventTypeByd",
"name": "bikeEventTypeById",
"description": null,
"args": [
{
@ -8818,6 +8855,51 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "editCopyConfig",
"description": "edit or add key value pair to copy config for cargo bikes",
"args": [
{
"name": "key",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"defaultValue": null
},
{
"name": "value",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
}
},
"defaultValue": null
}
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "createEquipment",
"description": "EQUIPMENT\ncreates new peace of unique Equipment",

File diff suppressed because it is too large Load Diff

@ -3,6 +3,8 @@
"extends": "./tsconfig.base.json",
"compilerOptions": {
"outDir": "./out-tsc/app",
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"types": []
},
"files": [

@ -8,6 +8,7 @@
"downlevelIteration": true,
"resolveJsonModule": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"moduleResolution": "node",
"importHelpers": true,
"target": "es2015",

@ -13,5 +13,9 @@
{
"path": "./tsconfig.spec.json"
}
]
],
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}

Loading…
Cancel
Save