| @@ -2984,6 +2984,398 @@ paths: | |||
| $ref: '#/components/schemas/UserTripEvent' | |||
| required: true | |||
| deprecated: false | |||
| /api/user_zones: | |||
| get: | |||
| operationId: api_user_zones_get_collection | |||
| tags: | |||
| - UserZone | |||
| responses: | |||
| '200': | |||
| description: 'UserZone collection' | |||
| content: | |||
| application/ld+json: | |||
| schema: | |||
| type: object | |||
| properties: | |||
| member: { type: array, items: { $ref: '#/components/schemas/UserZone.jsonld' } } | |||
| totalItems: { type: integer, minimum: 0 } | |||
| view: { type: object, properties: { '@id': { type: string, format: iri-reference }, '@type': { type: string }, first: { type: string, format: iri-reference }, last: { type: string, format: iri-reference }, previous: { type: string, format: iri-reference }, next: { type: string, format: iri-reference } }, example: { '@id': string, type: string, first: string, last: string, previous: string, next: string } } | |||
| search: { type: object, properties: { '@type': { type: string }, template: { type: string }, variableRepresentation: { type: string }, mapping: { type: array, items: { type: object, properties: { '@type': { type: string }, variable: { type: string }, property: { type: [string, 'null'] }, required: { type: boolean } } } } } } | |||
| required: | |||
| - member | |||
| '403': | |||
| description: Forbidden | |||
| content: | |||
| application/ld+json: | |||
| schema: | |||
| $ref: '#/components/schemas/Error.jsonld' | |||
| application/problem+json: | |||
| schema: | |||
| $ref: '#/components/schemas/Error' | |||
| application/json: | |||
| schema: | |||
| $ref: '#/components/schemas/Error' | |||
| links: { } | |||
| summary: 'Retrieves the collection of UserZone resources.' | |||
| description: 'Retrieves the collection of UserZone resources.' | |||
| parameters: | |||
| - | |||
| name: page | |||
| in: query | |||
| description: 'The collection page number' | |||
| required: false | |||
| deprecated: false | |||
| allowEmptyValue: true | |||
| schema: | |||
| type: integer | |||
| default: 1 | |||
| style: form | |||
| explode: false | |||
| allowReserved: false | |||
| - | |||
| name: itemsPerPage | |||
| in: query | |||
| description: 'The number of items per page' | |||
| required: false | |||
| deprecated: false | |||
| allowEmptyValue: true | |||
| schema: | |||
| type: integer | |||
| default: 50 | |||
| minimum: 0 | |||
| maximum: 200 | |||
| style: form | |||
| explode: false | |||
| allowReserved: false | |||
| - | |||
| name: user | |||
| in: query | |||
| description: '' | |||
| required: false | |||
| deprecated: false | |||
| allowEmptyValue: false | |||
| schema: | |||
| type: string | |||
| style: form | |||
| explode: false | |||
| allowReserved: false | |||
| - | |||
| name: 'user[]' | |||
| in: query | |||
| description: '' | |||
| required: false | |||
| deprecated: false | |||
| allowEmptyValue: false | |||
| schema: | |||
| type: array | |||
| items: | |||
| type: string | |||
| style: form | |||
| explode: true | |||
| allowReserved: false | |||
| - | |||
| name: zone | |||
| in: query | |||
| description: '' | |||
| required: false | |||
| deprecated: false | |||
| allowEmptyValue: false | |||
| schema: | |||
| type: string | |||
| style: form | |||
| explode: false | |||
| allowReserved: false | |||
| - | |||
| name: 'zone[]' | |||
| in: query | |||
| description: '' | |||
| required: false | |||
| deprecated: false | |||
| allowEmptyValue: false | |||
| schema: | |||
| type: array | |||
| items: | |||
| type: string | |||
| style: form | |||
| explode: true | |||
| allowReserved: false | |||
| - | |||
| name: custom_json_filter | |||
| in: query | |||
| description: '' | |||
| required: false | |||
| deprecated: false | |||
| allowEmptyValue: false | |||
| schema: | |||
| type: string | |||
| style: form | |||
| explode: false | |||
| allowReserved: false | |||
| - | |||
| name: custom_json_order | |||
| in: query | |||
| description: '' | |||
| required: false | |||
| deprecated: false | |||
| allowEmptyValue: true | |||
| schema: | |||
| type: string | |||
| style: form | |||
| explode: false | |||
| allowReserved: false | |||
| deprecated: false | |||
| post: | |||
| operationId: api_user_zones_post | |||
| tags: | |||
| - UserZone | |||
| responses: | |||
| '201': | |||
| description: 'UserZone resource created' | |||
| content: | |||
| application/ld+json: | |||
| schema: | |||
| $ref: '#/components/schemas/UserZone.jsonld' | |||
| links: { } | |||
| '400': | |||
| description: 'Invalid input' | |||
| content: | |||
| application/ld+json: | |||
| schema: | |||
| $ref: '#/components/schemas/Error.jsonld' | |||
| application/problem+json: | |||
| schema: | |||
| $ref: '#/components/schemas/Error' | |||
| application/json: | |||
| schema: | |||
| $ref: '#/components/schemas/Error' | |||
| links: { } | |||
| '422': | |||
| description: 'An error occurred' | |||
| content: | |||
| application/ld+json: | |||
| schema: | |||
| $ref: '#/components/schemas/ConstraintViolation.jsonld-jsonld' | |||
| application/problem+json: | |||
| schema: | |||
| $ref: '#/components/schemas/ConstraintViolation-json' | |||
| application/json: | |||
| schema: | |||
| $ref: '#/components/schemas/ConstraintViolation-json' | |||
| links: { } | |||
| '403': | |||
| description: Forbidden | |||
| content: | |||
| application/ld+json: | |||
| schema: | |||
| $ref: '#/components/schemas/Error.jsonld' | |||
| application/problem+json: | |||
| schema: | |||
| $ref: '#/components/schemas/Error' | |||
| application/json: | |||
| schema: | |||
| $ref: '#/components/schemas/Error' | |||
| links: { } | |||
| summary: 'Creates a UserZone resource.' | |||
| description: 'Creates a UserZone resource.' | |||
| parameters: [] | |||
| requestBody: | |||
| description: 'The new UserZone resource' | |||
| content: | |||
| application/ld+json: | |||
| schema: | |||
| $ref: '#/components/schemas/UserZone.jsonld' | |||
| required: true | |||
| deprecated: false | |||
| '/api/user_zones/{id}': | |||
| get: | |||
| operationId: api_user_zones_id_get | |||
| tags: | |||
| - UserZone | |||
| responses: | |||
| '200': | |||
| description: 'UserZone resource' | |||
| content: | |||
| application/ld+json: | |||
| schema: | |||
| $ref: '#/components/schemas/UserZone.jsonld' | |||
| '403': | |||
| description: Forbidden | |||
| content: | |||
| application/ld+json: | |||
| schema: | |||
| $ref: '#/components/schemas/Error.jsonld' | |||
| application/problem+json: | |||
| schema: | |||
| $ref: '#/components/schemas/Error' | |||
| application/json: | |||
| schema: | |||
| $ref: '#/components/schemas/Error' | |||
| links: { } | |||
| '404': | |||
| description: 'Not found' | |||
| content: | |||
| application/ld+json: | |||
| schema: | |||
| $ref: '#/components/schemas/Error.jsonld' | |||
| application/problem+json: | |||
| schema: | |||
| $ref: '#/components/schemas/Error' | |||
| application/json: | |||
| schema: | |||
| $ref: '#/components/schemas/Error' | |||
| links: { } | |||
| summary: 'Retrieves a UserZone resource.' | |||
| description: 'Retrieves a UserZone resource.' | |||
| parameters: | |||
| - | |||
| name: id | |||
| in: path | |||
| description: 'UserZone identifier' | |||
| required: true | |||
| deprecated: false | |||
| allowEmptyValue: false | |||
| schema: | |||
| type: string | |||
| style: simple | |||
| explode: false | |||
| allowReserved: false | |||
| deprecated: false | |||
| delete: | |||
| operationId: api_user_zones_id_delete | |||
| tags: | |||
| - UserZone | |||
| responses: | |||
| '204': | |||
| description: 'UserZone resource deleted' | |||
| '403': | |||
| description: Forbidden | |||
| content: | |||
| application/ld+json: | |||
| schema: | |||
| $ref: '#/components/schemas/Error.jsonld' | |||
| application/problem+json: | |||
| schema: | |||
| $ref: '#/components/schemas/Error' | |||
| application/json: | |||
| schema: | |||
| $ref: '#/components/schemas/Error' | |||
| links: { } | |||
| '404': | |||
| description: 'Not found' | |||
| content: | |||
| application/ld+json: | |||
| schema: | |||
| $ref: '#/components/schemas/Error.jsonld' | |||
| application/problem+json: | |||
| schema: | |||
| $ref: '#/components/schemas/Error' | |||
| application/json: | |||
| schema: | |||
| $ref: '#/components/schemas/Error' | |||
| links: { } | |||
| summary: 'Removes the UserZone resource.' | |||
| description: 'Removes the UserZone resource.' | |||
| parameters: | |||
| - | |||
| name: id | |||
| in: path | |||
| description: 'UserZone identifier' | |||
| required: true | |||
| deprecated: false | |||
| allowEmptyValue: false | |||
| schema: | |||
| type: string | |||
| style: simple | |||
| explode: false | |||
| allowReserved: false | |||
| deprecated: false | |||
| patch: | |||
| operationId: api_user_zones_id_patch | |||
| tags: | |||
| - UserZone | |||
| responses: | |||
| '200': | |||
| description: 'UserZone resource updated' | |||
| content: | |||
| application/ld+json: | |||
| schema: | |||
| $ref: '#/components/schemas/UserZone.jsonld' | |||
| links: { } | |||
| '400': | |||
| description: 'Invalid input' | |||
| content: | |||
| application/ld+json: | |||
| schema: | |||
| $ref: '#/components/schemas/Error.jsonld' | |||
| application/problem+json: | |||
| schema: | |||
| $ref: '#/components/schemas/Error' | |||
| application/json: | |||
| schema: | |||
| $ref: '#/components/schemas/Error' | |||
| links: { } | |||
| '422': | |||
| description: 'An error occurred' | |||
| content: | |||
| application/ld+json: | |||
| schema: | |||
| $ref: '#/components/schemas/ConstraintViolation.jsonld-jsonld' | |||
| application/problem+json: | |||
| schema: | |||
| $ref: '#/components/schemas/ConstraintViolation-json' | |||
| application/json: | |||
| schema: | |||
| $ref: '#/components/schemas/ConstraintViolation-json' | |||
| links: { } | |||
| '403': | |||
| description: Forbidden | |||
| content: | |||
| application/ld+json: | |||
| schema: | |||
| $ref: '#/components/schemas/Error.jsonld' | |||
| application/problem+json: | |||
| schema: | |||
| $ref: '#/components/schemas/Error' | |||
| application/json: | |||
| schema: | |||
| $ref: '#/components/schemas/Error' | |||
| links: { } | |||
| '404': | |||
| description: 'Not found' | |||
| content: | |||
| application/ld+json: | |||
| schema: | |||
| $ref: '#/components/schemas/Error.jsonld' | |||
| application/problem+json: | |||
| schema: | |||
| $ref: '#/components/schemas/Error' | |||
| application/json: | |||
| schema: | |||
| $ref: '#/components/schemas/Error' | |||
| links: { } | |||
| summary: 'Updates the UserZone resource.' | |||
| description: 'Updates the UserZone resource.' | |||
| parameters: | |||
| - | |||
| name: id | |||
| in: path | |||
| description: 'UserZone identifier' | |||
| required: true | |||
| deprecated: false | |||
| allowEmptyValue: false | |||
| schema: | |||
| type: string | |||
| style: simple | |||
| explode: false | |||
| allowReserved: false | |||
| requestBody: | |||
| description: 'The updated UserZone resource' | |||
| content: | |||
| application/merge-patch+json: | |||
| schema: | |||
| $ref: '#/components/schemas/UserZone' | |||
| required: true | |||
| deprecated: false | |||
| /api/vessels: | |||
| get: | |||
| operationId: api_vessels_get_collection | |||
| @@ -4912,6 +5304,89 @@ components: | |||
| - eventIri | |||
| - locationIri | |||
| - date | |||
| UserZone: | |||
| type: object | |||
| description: '' | |||
| deprecated: false | |||
| properties: | |||
| dbId: | |||
| readOnly: true | |||
| type: | |||
| - integer | |||
| - 'null' | |||
| user: | |||
| readOnly: true | |||
| type: string | |||
| format: iri-reference | |||
| example: 'https://example.com/' | |||
| userIri: | |||
| type: | |||
| - string | |||
| - 'null' | |||
| format: iri-reference | |||
| example: 'https://example.com/' | |||
| zone: | |||
| readOnly: true | |||
| type: string | |||
| format: iri-reference | |||
| example: 'https://example.com/' | |||
| zoneIri: | |||
| type: | |||
| - string | |||
| - 'null' | |||
| format: iri-reference | |||
| example: 'https://example.com/' | |||
| UserZone.jsonld: | |||
| type: object | |||
| description: '' | |||
| deprecated: false | |||
| properties: | |||
| '@context': | |||
| readOnly: true | |||
| oneOf: | |||
| - | |||
| type: string | |||
| - | |||
| type: object | |||
| properties: | |||
| '@vocab': | |||
| type: string | |||
| hydra: | |||
| type: string | |||
| enum: ['http://www.w3.org/ns/hydra/core#'] | |||
| required: | |||
| - '@vocab' | |||
| - hydra | |||
| additionalProperties: true | |||
| '@id': | |||
| readOnly: true | |||
| type: string | |||
| '@type': | |||
| readOnly: true | |||
| type: string | |||
| dbId: | |||
| readOnly: true | |||
| type: | |||
| - integer | |||
| - 'null' | |||
| user: | |||
| readOnly: true | |||
| $ref: '#/components/schemas/User.jsonld' | |||
| userIri: | |||
| type: | |||
| - string | |||
| - 'null' | |||
| format: iri-reference | |||
| example: 'https://example.com/' | |||
| zone: | |||
| readOnly: true | |||
| $ref: '#/components/schemas/Zone.jsonld' | |||
| zoneIri: | |||
| type: | |||
| - string | |||
| - 'null' | |||
| format: iri-reference | |||
| example: 'https://example.com/' | |||
| Vessel: | |||
| type: object | |||
| description: '' | |||
| @@ -5167,6 +5642,8 @@ tags: | |||
| name: UserTrip | |||
| - | |||
| name: UserTripEvent | |||
| - | |||
| name: UserZone | |||
| - | |||
| name: Vessel | |||
| - | |||
| @@ -27,6 +27,7 @@ export abstract class AbstractDataFormComponent<T extends { [key: string]: any } | |||
| @Input() redirectAfterDelete?: string; | |||
| @Output() submit = new EventEmitter<FormSubmitEvent<T>>(); | |||
| @Output() deleted: EventEmitter<void> = new EventEmitter<void>(); | |||
| @Input() isInModal: boolean = false; | |||
| protected id?: string; | |||
| protected form!: FormGroup; | |||
| @@ -99,7 +100,11 @@ export abstract class AbstractDataFormComponent<T extends { [key: string]: any } | |||
| this.deleteFn!(this.id!).subscribe({ | |||
| next: () => { | |||
| this.deleted.emit(); | |||
| if (this.redirectAfterDelete && this.router) { | |||
| this.submit.emit({ | |||
| status: ModalStatus.Submitted, | |||
| data: null | |||
| }); | |||
| if (!this.isInModal && this.redirectAfterDelete && this.router) { | |||
| this.router.navigate([this.redirectAfterDelete]); | |||
| } | |||
| }, | |||
| @@ -434,6 +434,11 @@ export class ListComponent implements OnInit, AfterViewInit, OnDestroy { | |||
| delete this.dataFormComponentData.data; | |||
| } | |||
| this.dataFormComponentData = { | |||
| ...this.dataFormComponentData, | |||
| isInModal: true, | |||
| }; | |||
| this.appHelperService.openModal( | |||
| this.dataFormComponent, | |||
| this.dataFormComponentData, | |||
| @@ -449,7 +454,8 @@ export class ListComponent implements OnInit, AfterViewInit, OnDestroy { | |||
| // Create a new object instead of modifying the existing one | |||
| this.dataFormComponentData = { | |||
| ...this.dataFormComponentData, | |||
| data: element | |||
| data: element, | |||
| isInModal: true, | |||
| }; | |||
| this.appHelperService.openModal( | |||
| this.dataFormComponent, | |||
| @@ -244,6 +244,22 @@ export const userTripEventJsonldForm = new FormGroup({ | |||
| createdAt: new FormControl(null, []) | |||
| }); | |||
| export const userZoneForm = new FormGroup({ | |||
| dbId: new FormControl(null, []), | |||
| user: new FormControl(null, []), | |||
| userIri: new FormControl(null, []), | |||
| zone: new FormControl(null, []), | |||
| zoneIri: new FormControl(null, []) | |||
| }); | |||
| export const userZoneJsonldForm = new FormGroup({ | |||
| dbId: new FormControl(null, []), | |||
| user: new FormControl(null, []), | |||
| userIri: new FormControl(null, []), | |||
| zone: new FormControl(null, []), | |||
| zoneIri: new FormControl(null, []) | |||
| }); | |||
| export const vesselForm = new FormGroup({ | |||
| dbId: new FormControl(null, []), | |||
| name: new FormControl(null, [Validators.required]), | |||
| @@ -0,0 +1,58 @@ | |||
| <div class="spt-container"> | |||
| <div class="spt-form"> | |||
| @if (data !== undefined) { | |||
| <form [formGroup]="userZoneForm" (ngSubmit)="onSubmit()"> | |||
| @if (user) { | |||
| <div>{{ 'base_data.pilot' | translate }}: {{ user.fullName }}</div> | |||
| } @else { | |||
| <div class="row"> | |||
| <label for="userIri" class="form-label">{{ 'base_data.pilot' | translate }}*:</label> | |||
| <app-search-select #userSearchSelect | |||
| [formId]="'userIri'" | |||
| [formLabelLangKey]="'model.user'" | |||
| [documentForm]="userZoneForm" | |||
| [getDataFunction]="getUsers" | |||
| [displayedDataField]="'fullName'" | |||
| [listColDefinitions]="userColDefinitions" | |||
| [dataSet]="user" | |||
| > | |||
| </app-search-select> | |||
| <input id="userIri" type="hidden" formControlName="userIri" required/> | |||
| </div> | |||
| } | |||
| @if (zone) { | |||
| <div>{{ 'model.zone' | translate }}: {{ zone.name }}</div> | |||
| } @else { | |||
| <div class="col-12 mb-3"> | |||
| <label for="zoneIri" class="form-label">{{ 'model.zone' | translate }}*:</label> | |||
| <app-search-select #zoneSearchSelect | |||
| [formId]="'zoneIri'" | |||
| [formLabelLangKey]="'model.zone'" | |||
| [documentForm]="userZoneForm" | |||
| [getDataFunction]="getZones" | |||
| [displayedDataField]="'name'" | |||
| [listColDefinitions]="zoneColDefinitions" | |||
| [dataSet]="zone" | |||
| > | |||
| </app-search-select> | |||
| <input id="zoneIri" type="hidden" formControlName="zoneIri" required/> | |||
| </div> | |||
| } | |||
| </form> | |||
| } | |||
| </div> | |||
| <div class="row"> | |||
| <div class="col-12 mb-3"> | |||
| <button type="submit" class="btn btn-primary" (click)="onSubmit()"> | |||
| {{ 'basic.save' | translate }} | |||
| </button> | |||
| @if (isEditMode()) { | |||
| <button type="button" class="ms-3 btn btn-primary" (click)="onDelete()"> | |||
| {{ 'basic.delete' | translate }} {{ 'model.user_trip' | translate }} | |||
| </button> | |||
| } | |||
| </div> | |||
| </div> | |||
| </div> | |||
| @@ -0,0 +1,23 @@ | |||
| import { ComponentFixture, TestBed } from '@angular/core/testing'; | |||
| import { UserZoneFormComponent } from './user-zone-form.component'; | |||
| describe('UserZoneFormComponent', () => { | |||
| let component: UserZoneFormComponent; | |||
| let fixture: ComponentFixture<UserZoneFormComponent>; | |||
| beforeEach(async () => { | |||
| await TestBed.configureTestingModule({ | |||
| declarations: [UserZoneFormComponent] | |||
| }) | |||
| .compileComponents(); | |||
| fixture = TestBed.createComponent(UserZoneFormComponent); | |||
| component = fixture.componentInstance; | |||
| fixture.detectChanges(); | |||
| }); | |||
| it('should create', () => { | |||
| expect(component).toBeTruthy(); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,194 @@ | |||
| import { Component } from '@angular/core'; | |||
| import { | |||
| UserJsonld, | |||
| UserService, | |||
| UserZoneJsonld, UserZoneService, | |||
| ZoneJsonld, ZoneService | |||
| } from "@app/core/api/v1"; | |||
| import {userZoneForm} from "@app/_forms/apiForms"; | |||
| import {ListColDefinition} from "@app/_components/list/list-col-definition"; | |||
| import {AppHelperService} from "@app/_helpers/app-helper.service"; | |||
| import {TranslateService} from "@ngx-translate/core"; | |||
| import {Router} from "@angular/router"; | |||
| import {SearchSelectComponent} from "@app/_components/search-select/search-select.component"; | |||
| import {ListGetDataFunctionType} from "@app/_components/list/list-get-data-function-type"; | |||
| import {of, switchMap} from "rxjs"; | |||
| import {map} from "rxjs/operators"; | |||
| import {AbstractDataFormComponent} from "@app/_components/_abstract/abstract-data-form-component"; | |||
| @Component({ | |||
| selector: 'app-user-zone-form', | |||
| templateUrl: './user-zone-form.component.html', | |||
| styleUrl: './user-zone-form.component.scss' | |||
| }) | |||
| export class UserZoneFormComponent extends AbstractDataFormComponent<UserZoneJsonld> { | |||
| protected readonly userZoneForm = userZoneForm; | |||
| protected userColDefinitions: ListColDefinition[]; | |||
| protected zoneColDefinitions: ListColDefinition[]; | |||
| protected user?: UserJsonld; | |||
| protected zone?: ZoneJsonld; | |||
| constructor( | |||
| protected userZoneService: UserZoneService, | |||
| protected userService: UserService, | |||
| protected zoneService: ZoneService, | |||
| appHelperService: AppHelperService, | |||
| translateService: TranslateService, | |||
| router: Router | |||
| ) { | |||
| super( | |||
| userZoneForm, | |||
| appHelperService, | |||
| (data: UserZoneJsonld) => this.userZoneService.userZonesPost(this.appHelperService.convertJsonldToJson(data)), | |||
| (id: string | number, data: UserZoneJsonld) => | |||
| this.userZoneService.userZonesIdPatch( | |||
| id.toString(), | |||
| this.appHelperService.convertJsonldToJson(data) | |||
| ), | |||
| (id: string | number) => userZoneService.userZonesIdDelete(id.toString()), | |||
| translateService, | |||
| router | |||
| ); | |||
| this.userColDefinitions = SearchSelectComponent.getDefaultColDefUsers(); | |||
| this.zoneColDefinitions = SearchSelectComponent.getDefaultColDefZones(); | |||
| } | |||
| override ngOnInit() { | |||
| super.ngOnInit(); | |||
| // Setze User und Zone aus den übergebenen Daten | |||
| if (this.data?.user && !this.user) { | |||
| this.user = this.data?.user; | |||
| } | |||
| if (this.data?.zone && !this.zone) { | |||
| this.zone = this.data?.zone; | |||
| } | |||
| // Validierung: Mindestens User oder Zone muss vorgegeben sein | |||
| if (!this.user && !this.zone) { | |||
| throw new Error('UserZoneFormComponent: Either user or zone has to be given'); | |||
| } | |||
| // Beide gleichzeitig vorgegeben ist auch nicht erlaubt (würde keinen Sinn machen) | |||
| if (this.user && this.zone) { | |||
| throw new Error('UserZoneFormComponent: Either user or zone has to be given'); | |||
| } | |||
| // Setze die FormControl-Werte wenn vorgegeben | |||
| if (this.zone && !this.data!.zoneIri!) { | |||
| this.data!.zoneIri = this.zone.id!; | |||
| this.form.get('zoneIri')?.setValue(this.zone.id!); | |||
| } | |||
| if (this.user && !this.data!.userIri!) { | |||
| this.data!.userIri = this.user.id!; | |||
| this.form.get('userIri')?.setValue(this.user.id!); | |||
| } | |||
| } | |||
| getUsers: ListGetDataFunctionType = ( | |||
| index: number, | |||
| pageSize: number, | |||
| term?: string, | |||
| ) => { | |||
| // Hole alle Benutzer mit isPilot=true | |||
| return this.userService.usersGetCollection( | |||
| index, | |||
| pageSize, | |||
| undefined, | |||
| undefined, | |||
| term, | |||
| '{"isPilot":true}' | |||
| ).pipe( | |||
| switchMap(usersResponse => { | |||
| // Wenn keine Zone vorhanden ist, gib alle Benutzer zurück | |||
| if (!this.zone?.id) { | |||
| return of(usersResponse); | |||
| } | |||
| // Hole alle UserZones für diese Zone | |||
| return this.userZoneService.userZonesGetCollection( | |||
| 1, | |||
| 100, | |||
| undefined, // user | |||
| undefined, // user2 | |||
| this.zone.id, // zone | |||
| undefined, | |||
| ).pipe( | |||
| map(userZonesResponse => { | |||
| // Extrahiere die User-IDs aus den UserZones | |||
| const usedUserIds = new Set( | |||
| userZonesResponse.member?.map( | |||
| (userZone: UserZoneJsonld) => userZone.userIri | |||
| ) || [] | |||
| ); | |||
| // Filtere die Benutzer, die noch nicht zugeordnet sind | |||
| if (usersResponse.member) { | |||
| usersResponse.member = usersResponse.member.filter( | |||
| (user: UserJsonld) => !usedUserIds.has(user.id!) | |||
| ); | |||
| // Aktualisiere die totalItems Anzahl | |||
| if (usersResponse.totalItems) { | |||
| usersResponse.totalItems = usersResponse.member.length; | |||
| } | |||
| } | |||
| return usersResponse; | |||
| }) | |||
| ); | |||
| }) | |||
| ); | |||
| } | |||
| getZones: ListGetDataFunctionType = ( | |||
| index: number, | |||
| pageSize: number, | |||
| term?: string, | |||
| ) => { | |||
| return this.zoneService.zonesGetCollection( | |||
| index, | |||
| pageSize, | |||
| undefined, | |||
| undefined, | |||
| term | |||
| ).pipe( | |||
| switchMap(zonesResponse => { | |||
| // Wenn kein User vorhanden ist, gib alle Zonen zurück | |||
| if (!this.user?.id) { | |||
| return of(zonesResponse); | |||
| } | |||
| // Hole alle UserZones für diesen User | |||
| return this.userZoneService.userZonesGetCollection( | |||
| 1, | |||
| 100, | |||
| this.user.id, // user | |||
| undefined, // user2 | |||
| undefined // zone | |||
| ).pipe( | |||
| map(userZonesResponse => { | |||
| // Extrahiere die Zone-IDs aus den UserZones | |||
| const usedZoneIds = new Set( | |||
| userZonesResponse.member?.map( | |||
| (userZone: UserZoneJsonld) => userZone.zoneIri | |||
| ) || [] | |||
| ); | |||
| // Filtere die Zonen, die noch nicht zugeordnet sind | |||
| if (zonesResponse.member) { | |||
| zonesResponse.member = zonesResponse.member.filter( | |||
| (zone: ZoneJsonld) => !usedZoneIds.has(zone.id!) | |||
| ); | |||
| // Aktualisiere die totalItems Anzahl | |||
| if (zonesResponse.totalItems) { | |||
| zonesResponse.totalItems = zonesResponse.member.length; | |||
| } | |||
| } | |||
| return zonesResponse; | |||
| }) | |||
| ); | |||
| }) | |||
| ); | |||
| } | |||
| } | |||
| @@ -0,0 +1,12 @@ | |||
| <div class="spt-container"> | |||
| <app-list #listComponent | |||
| [listId]="'userZoneList'" | |||
| [getDataFunction]="getData" | |||
| [listColDefinitions]="listColDefinitions" | |||
| [dataFormComponent]="userTripLocationFormComponent" | |||
| [dataFormComponentData]="dataFormComponentData" | |||
| [deleteItemFunction]="deleteItemFunction" | |||
| [showCreateButton]="showCreateButton" | |||
| [showDetailButton]="false" | |||
| ></app-list> | |||
| </div> | |||
| @@ -0,0 +1,23 @@ | |||
| import { ComponentFixture, TestBed } from '@angular/core/testing'; | |||
| import { UserZoneListComponent } from './user-zone-list.component'; | |||
| describe('UserZoneListComponent', () => { | |||
| let component: UserZoneListComponent; | |||
| let fixture: ComponentFixture<UserZoneListComponent>; | |||
| beforeEach(async () => { | |||
| await TestBed.configureTestingModule({ | |||
| declarations: [UserZoneListComponent] | |||
| }) | |||
| .compileComponents(); | |||
| fixture = TestBed.createComponent(UserZoneListComponent); | |||
| component = fixture.componentInstance; | |||
| fixture.detectChanges(); | |||
| }); | |||
| it('should create', () => { | |||
| expect(component).toBeTruthy(); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,102 @@ | |||
| import {Component, Input, ViewChild} from '@angular/core'; | |||
| import {UserJsonld, UserZoneService, ZoneJsonld} from "@app/core/api/v1"; | |||
| import {ListComponent} from "@app/_components/list/list.component"; | |||
| import {ListColDefinition} from "@app/_components/list/list-col-definition"; | |||
| import {AppHelperService} from "@app/_helpers/app-helper.service"; | |||
| import {FilterBarComponent} from "@app/_components/filter-bar/filter-bar.component"; | |||
| import {ListGetDataFunctionType} from "@app/_components/list/list-get-data-function-type"; | |||
| import {Observable} from "rxjs"; | |||
| import {UserZoneFormComponent} from "@app/_views/user-zone/user-zone-form/user-zone-form.component"; | |||
| @Component({ | |||
| selector: 'app-user-zone-list', | |||
| templateUrl: './user-zone-list.component.html', | |||
| styleUrl: './user-zone-list.component.scss' | |||
| }) | |||
| export class UserZoneListComponent { | |||
| @Input() public user?: UserJsonld; | |||
| @Input() public zone?: ZoneJsonld; | |||
| @Input() public showCreateButton: boolean; | |||
| @ViewChild("listComponent", {static: false}) listComponent!: ListComponent; | |||
| protected readonly userTripLocationFormComponent = UserZoneFormComponent; | |||
| protected listColDefinitions!: ListColDefinition[]; | |||
| protected dataFormComponentData: any; | |||
| constructor( | |||
| private userZoneService: UserZoneService, | |||
| protected appHelperService: AppHelperService, | |||
| ) { | |||
| this.showCreateButton = true; | |||
| this.listColDefinitions = [ | |||
| { | |||
| name: 'userFirstname', | |||
| text: 'users.firstname', | |||
| type: ListComponent.COLUMN_TYPE_TEXT_BOLD, | |||
| field: 'firstName', | |||
| subResource: 'user', | |||
| sortable: true, | |||
| sortingSubResource: 'user', | |||
| sortingFieldName: 'firstName', | |||
| filterType: FilterBarComponent.FILTER_TYPE_TEXT, | |||
| } as ListColDefinition, | |||
| { | |||
| name: 'userLastname', | |||
| text: 'users.lastname', | |||
| type: ListComponent.COLUMN_TYPE_TEXT_BOLD, | |||
| field: 'lastName', | |||
| subResource: 'user', | |||
| sortable: true, | |||
| sortingSubResource: 'user', | |||
| sortingFieldName: 'lastName', | |||
| filterType: FilterBarComponent.FILTER_TYPE_TEXT, | |||
| } as ListColDefinition, | |||
| { | |||
| name: 'zoneName', | |||
| text: 'model.zone', | |||
| type: ListComponent.COLUMN_TYPE_TEXT, | |||
| field: 'name', | |||
| subResource: 'zone', | |||
| sortable: true, | |||
| sortingSubResource: 'zone', | |||
| sortingFieldName: 'name', | |||
| filterType: FilterBarComponent.FILTER_TYPE_TEXT, | |||
| } as ListColDefinition, | |||
| ]; | |||
| } | |||
| ngOnInit() { | |||
| this.dataFormComponentData = {}; | |||
| if (this.zone) { | |||
| this.dataFormComponentData['zone'] = this.zone; | |||
| } | |||
| if (this.user) { | |||
| this.dataFormComponentData['user'] = this.user; | |||
| } | |||
| } | |||
| ngAfterViewInit(): void { | |||
| this.listComponent.getData(); | |||
| } | |||
| getData: ListGetDataFunctionType = ( | |||
| index: number, | |||
| pageSize: number, | |||
| term?: string, | |||
| ) => { | |||
| return this.userZoneService.userZonesGetCollection( | |||
| index, | |||
| pageSize, | |||
| this.user ? this.user.id : undefined, | |||
| undefined, | |||
| this.zone ? this.zone.id : undefined, | |||
| undefined, | |||
| this.listComponent.getFilterJsonString(), | |||
| this.listComponent.getSortingJsonString() | |||
| ); | |||
| } | |||
| get deleteItemFunction(): (id: string) => Observable<any> { | |||
| return (id: string) => this.userZoneService.userZonesIdDelete(id); | |||
| } | |||
| } | |||
| @@ -0,0 +1 @@ | |||
| <p>user-zone works!</p> | |||
| @@ -0,0 +1,23 @@ | |||
| import { ComponentFixture, TestBed } from '@angular/core/testing'; | |||
| import { UserZoneComponent } from './user-zone.component'; | |||
| describe('UserZoneComponent', () => { | |||
| let component: UserZoneComponent; | |||
| let fixture: ComponentFixture<UserZoneComponent>; | |||
| beforeEach(async () => { | |||
| await TestBed.configureTestingModule({ | |||
| declarations: [UserZoneComponent] | |||
| }) | |||
| .compileComponents(); | |||
| fixture = TestBed.createComponent(UserZoneComponent); | |||
| component = fixture.componentInstance; | |||
| fixture.detectChanges(); | |||
| }); | |||
| it('should create', () => { | |||
| expect(component).toBeTruthy(); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,10 @@ | |||
| import { Component } from '@angular/core'; | |||
| @Component({ | |||
| selector: 'app-user-zone', | |||
| templateUrl: './user-zone.component.html', | |||
| styleUrl: './user-zone.component.scss' | |||
| }) | |||
| export class UserZoneComponent { | |||
| } | |||
| @@ -15,5 +15,10 @@ | |||
| [user]="user" | |||
| ></app-user-trip-list> | |||
| </mat-tab> | |||
| <mat-tab label="{{ 'model.user_zones' | translate }}"> | |||
| <app-user-zone-list | |||
| [user]="user" | |||
| ></app-user-zone-list> | |||
| </mat-tab> | |||
| </mat-tab-group> | |||
| </div> | |||
| @@ -1,7 +1,17 @@ | |||
| @if (zone) { | |||
| <div class="spt-container"> | |||
| <app-zone-form | |||
| [data]="zone" | |||
| ></app-zone-form> | |||
| <mat-tab-group> | |||
| <mat-tab label="{{ 'basic.details' | translate }}"> | |||
| <app-zone-form | |||
| [data]="zone" | |||
| ></app-zone-form> | |||
| </mat-tab> | |||
| <mat-tab label="{{ 'model.user_zones' | translate }}"> | |||
| <app-user-zone-list | |||
| [zone]="zone" | |||
| ></app-user-zone-list> | |||
| </mat-tab> | |||
| </mat-tab-group> | |||
| </div> | |||
| } | |||
| @@ -74,6 +74,9 @@ import { ImageUploadComponent } from './_components/image-upload/image-upload.co | |||
| import { TripLocationListComponent } from './_views/trip/trip-location-list/trip-location-list.component'; | |||
| import { TripLocationFormComponent } from './_views/trip/trip-location-form/trip-location-form.component'; | |||
| import { UserTripEventFormComponent } from './_views/user-trip-event/user-trip-event-form/user-trip-event-form.component'; | |||
| import { UserZoneListComponent } from '@app/_views/user-zone/user-zone-list/user-zone-list.component'; | |||
| import { UserZoneComponent } from './_views/user-zone/user-zone.component'; | |||
| import { UserZoneFormComponent } from './_views/user-zone/user-zone-form/user-zone-form.component'; | |||
| registerLocaleData(localeDe, 'de-DE'); | |||
| @@ -173,6 +176,9 @@ export function HttpLoaderFactory(http: HttpClient) { | |||
| TripLocationListComponent, | |||
| TripLocationFormComponent, | |||
| UserTripEventFormComponent, | |||
| UserZoneListComponent, | |||
| UserZoneComponent, | |||
| UserZoneFormComponent, | |||
| ], | |||
| providers: [ | |||
| {provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true}, | |||
| @@ -12,6 +12,7 @@ api/tripLocation.service.ts | |||
| api/user.service.ts | |||
| api/userTrip.service.ts | |||
| api/userTripEvent.service.ts | |||
| api/userZone.service.ts | |||
| api/vessel.service.ts | |||
| api/zone.service.ts | |||
| configuration.ts | |||
| @@ -29,6 +30,7 @@ model/apiTripLocationsGetCollection200Response.ts | |||
| model/apiTripsGetCollection200Response.ts | |||
| model/apiUserTripEventsGetCollection200Response.ts | |||
| model/apiUserTripsGetCollection200Response.ts | |||
| model/apiUserZonesGetCollection200Response.ts | |||
| model/apiUsersGetCollection200Response.ts | |||
| model/apiVesselsGetCollection200Response.ts | |||
| model/apiZonesGetCollection200Response.ts | |||
| @@ -58,6 +60,8 @@ model/userTrip.ts | |||
| model/userTripEvent.ts | |||
| model/userTripEventJsonld.ts | |||
| model/userTripJsonld.ts | |||
| model/userZone.ts | |||
| model/userZoneJsonld.ts | |||
| model/vessel.ts | |||
| model/vesselJsonld.ts | |||
| model/zone.ts | |||
| @@ -18,8 +18,10 @@ export * from './userTrip.service'; | |||
| import { UserTripService } from './userTrip.service'; | |||
| export * from './userTripEvent.service'; | |||
| import { UserTripEventService } from './userTripEvent.service'; | |||
| export * from './userZone.service'; | |||
| import { UserZoneService } from './userZone.service'; | |||
| export * from './vessel.service'; | |||
| import { VesselService } from './vessel.service'; | |||
| export * from './zone.service'; | |||
| import { ZoneService } from './zone.service'; | |||
| export const APIS = [AuthService, EventService, LocationService, MediaObjectService, ShippingCompanyService, TripService, TripLocationService, UserService, UserTripService, UserTripEventService, VesselService, ZoneService]; | |||
| export const APIS = [AuthService, EventService, LocationService, MediaObjectService, ShippingCompanyService, TripService, TripLocationService, UserService, UserTripService, UserTripEventService, UserZoneService, VesselService, ZoneService]; | |||
| @@ -0,0 +1,541 @@ | |||
| /** | |||
| * Imaq Platform | |||
| * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) | |||
| * | |||
| * The version of the OpenAPI document: 1.0.0 | |||
| * | |||
| * | |||
| * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). | |||
| * https://openapi-generator.tech | |||
| * Do not edit the class manually. | |||
| */ | |||
| /* tslint:disable:no-unused-variable member-ordering */ | |||
| import { Inject, Injectable, Optional } from '@angular/core'; | |||
| import { HttpClient, HttpHeaders, HttpParams, | |||
| HttpResponse, HttpEvent, HttpParameterCodec, HttpContext | |||
| } from '@angular/common/http'; | |||
| import { CustomHttpParameterCodec } from '../encoder'; | |||
| import { Observable } from 'rxjs'; | |||
| // @ts-ignore | |||
| import { ApiUserZonesGetCollection200Response } from '../model/apiUserZonesGetCollection200Response'; | |||
| // @ts-ignore | |||
| import { ConstraintViolationJson } from '../model/constraintViolationJson'; | |||
| // @ts-ignore | |||
| import { ConstraintViolationJsonldJsonld } from '../model/constraintViolationJsonldJsonld'; | |||
| // @ts-ignore | |||
| import { ErrorJsonld } from '../model/errorJsonld'; | |||
| // @ts-ignore | |||
| import { UserZone } from '../model/userZone'; | |||
| // @ts-ignore | |||
| import { UserZoneJsonld } from '../model/userZoneJsonld'; | |||
| // @ts-ignore | |||
| import { BASE_PATH, COLLECTION_FORMATS } from '../variables'; | |||
| import { Configuration } from '../configuration'; | |||
| @Injectable({ | |||
| providedIn: 'root' | |||
| }) | |||
| export class UserZoneService { | |||
| protected basePath = 'http://localhost'; | |||
| public defaultHeaders = new HttpHeaders(); | |||
| public configuration = new Configuration(); | |||
| public encoder: HttpParameterCodec; | |||
| constructor(protected httpClient: HttpClient, @Optional()@Inject(BASE_PATH) basePath: string|string[], @Optional() configuration: Configuration) { | |||
| if (configuration) { | |||
| this.configuration = configuration; | |||
| } | |||
| if (typeof this.configuration.basePath !== 'string') { | |||
| if (Array.isArray(basePath) && basePath.length > 0) { | |||
| basePath = basePath[0]; | |||
| } | |||
| if (typeof basePath !== 'string') { | |||
| basePath = this.basePath; | |||
| } | |||
| this.configuration.basePath = basePath; | |||
| } | |||
| this.encoder = this.configuration.encoder || new CustomHttpParameterCodec(); | |||
| } | |||
| // @ts-ignore | |||
| private addToHttpParams(httpParams: HttpParams, value: any, key?: string): HttpParams { | |||
| if (typeof value === "object" && value instanceof Date === false) { | |||
| httpParams = this.addToHttpParamsRecursive(httpParams, value); | |||
| } else { | |||
| httpParams = this.addToHttpParamsRecursive(httpParams, value, key); | |||
| } | |||
| return httpParams; | |||
| } | |||
| private addToHttpParamsRecursive(httpParams: HttpParams, value?: any, key?: string): HttpParams { | |||
| if (value == null) { | |||
| return httpParams; | |||
| } | |||
| if (typeof value === "object") { | |||
| if (Array.isArray(value)) { | |||
| (value as any[]).forEach( elem => httpParams = this.addToHttpParamsRecursive(httpParams, elem, key)); | |||
| } else if (value instanceof Date) { | |||
| if (key != null) { | |||
| httpParams = httpParams.append(key, (value as Date).toISOString().substring(0, 10)); | |||
| } else { | |||
| throw Error("key may not be null if value is Date"); | |||
| } | |||
| } else { | |||
| Object.keys(value).forEach( k => httpParams = this.addToHttpParamsRecursive( | |||
| httpParams, value[k], key != null ? `${key}.${k}` : k)); | |||
| } | |||
| } else if (key != null) { | |||
| httpParams = httpParams.append(key, value); | |||
| } else { | |||
| throw Error("key may not be null if value is not object or array"); | |||
| } | |||
| return httpParams; | |||
| } | |||
| /** | |||
| * Retrieves the collection of UserZone resources. | |||
| * Retrieves the collection of UserZone resources. | |||
| * @param page The collection page number | |||
| * @param itemsPerPage The number of items per page | |||
| * @param user | |||
| * @param user2 | |||
| * @param zone | |||
| * @param zone2 | |||
| * @param customJsonFilter | |||
| * @param customJsonOrder | |||
| * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. | |||
| * @param reportProgress flag to report request and response progress. | |||
| */ | |||
| public userZonesGetCollection(page?: number, itemsPerPage?: number, user?: string, user2?: Array<string>, zone?: string, zone2?: Array<string>, customJsonFilter?: string, customJsonOrder?: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/ld+json' | 'application/problem+json' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<ApiUserZonesGetCollection200Response>; | |||
| public userZonesGetCollection(page?: number, itemsPerPage?: number, user?: string, user2?: Array<string>, zone?: string, zone2?: Array<string>, customJsonFilter?: string, customJsonOrder?: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/ld+json' | 'application/problem+json' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<HttpResponse<ApiUserZonesGetCollection200Response>>; | |||
| public userZonesGetCollection(page?: number, itemsPerPage?: number, user?: string, user2?: Array<string>, zone?: string, zone2?: Array<string>, customJsonFilter?: string, customJsonOrder?: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/ld+json' | 'application/problem+json' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<HttpEvent<ApiUserZonesGetCollection200Response>>; | |||
| public userZonesGetCollection(page?: number, itemsPerPage?: number, user?: string, user2?: Array<string>, zone?: string, zone2?: Array<string>, customJsonFilter?: string, customJsonOrder?: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/ld+json' | 'application/problem+json' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<any> { | |||
| let localVarQueryParameters = new HttpParams({encoder: this.encoder}); | |||
| if (page !== undefined && page !== null) { | |||
| localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, | |||
| <any>page, 'page'); | |||
| } | |||
| if (itemsPerPage !== undefined && itemsPerPage !== null) { | |||
| localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, | |||
| <any>itemsPerPage, 'itemsPerPage'); | |||
| } | |||
| if (user !== undefined && user !== null) { | |||
| localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, | |||
| <any>user, 'user'); | |||
| } | |||
| if (user2) { | |||
| user2.forEach((element) => { | |||
| localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, | |||
| <any>element, 'user[]'); | |||
| }) | |||
| } | |||
| if (zone !== undefined && zone !== null) { | |||
| localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, | |||
| <any>zone, 'zone'); | |||
| } | |||
| if (zone2) { | |||
| zone2.forEach((element) => { | |||
| localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, | |||
| <any>element, 'zone[]'); | |||
| }) | |||
| } | |||
| if (customJsonFilter !== undefined && customJsonFilter !== null) { | |||
| localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, | |||
| <any>customJsonFilter, 'custom_json_filter'); | |||
| } | |||
| if (customJsonOrder !== undefined && customJsonOrder !== null) { | |||
| localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, | |||
| <any>customJsonOrder, 'custom_json_order'); | |||
| } | |||
| let localVarHeaders = this.defaultHeaders; | |||
| let localVarCredential: string | undefined; | |||
| // authentication (JWT) required | |||
| localVarCredential = this.configuration.lookupCredential('JWT'); | |||
| if (localVarCredential) { | |||
| localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential); | |||
| } | |||
| let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; | |||
| if (localVarHttpHeaderAcceptSelected === undefined) { | |||
| // to determine the Accept header | |||
| const httpHeaderAccepts: string[] = [ | |||
| 'application/ld+json', | |||
| 'application/problem+json', | |||
| 'application/json' | |||
| ]; | |||
| localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); | |||
| } | |||
| if (localVarHttpHeaderAcceptSelected !== undefined) { | |||
| localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); | |||
| } | |||
| let localVarHttpContext: HttpContext | undefined = options && options.context; | |||
| if (localVarHttpContext === undefined) { | |||
| localVarHttpContext = new HttpContext(); | |||
| } | |||
| let localVarTransferCache: boolean | undefined = options && options.transferCache; | |||
| if (localVarTransferCache === undefined) { | |||
| localVarTransferCache = true; | |||
| } | |||
| let responseType_: 'text' | 'json' | 'blob' = 'json'; | |||
| if (localVarHttpHeaderAcceptSelected) { | |||
| if (localVarHttpHeaderAcceptSelected.startsWith('text')) { | |||
| responseType_ = 'text'; | |||
| } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { | |||
| responseType_ = 'json'; | |||
| } else { | |||
| responseType_ = 'blob'; | |||
| } | |||
| } | |||
| let localVarPath = `/api/user_zones`; | |||
| return this.httpClient.request<ApiUserZonesGetCollection200Response>('get', `${this.configuration.basePath}${localVarPath}`, | |||
| { | |||
| context: localVarHttpContext, | |||
| params: localVarQueryParameters, | |||
| responseType: <any>responseType_, | |||
| withCredentials: this.configuration.withCredentials, | |||
| headers: localVarHeaders, | |||
| observe: observe, | |||
| transferCache: localVarTransferCache, | |||
| reportProgress: reportProgress | |||
| } | |||
| ); | |||
| } | |||
| /** | |||
| * Removes the UserZone resource. | |||
| * Removes the UserZone resource. | |||
| * @param id UserZone identifier | |||
| * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. | |||
| * @param reportProgress flag to report request and response progress. | |||
| */ | |||
| public userZonesIdDelete(id: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/ld+json' | 'application/problem+json' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<any>; | |||
| public userZonesIdDelete(id: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/ld+json' | 'application/problem+json' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<HttpResponse<any>>; | |||
| public userZonesIdDelete(id: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/ld+json' | 'application/problem+json' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<HttpEvent<any>>; | |||
| public userZonesIdDelete(id: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/ld+json' | 'application/problem+json' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<any> { | |||
| if (id === null || id === undefined) { | |||
| throw new Error('Required parameter id was null or undefined when calling userZonesIdDelete.'); | |||
| } | |||
| let localVarHeaders = this.defaultHeaders; | |||
| let localVarCredential: string | undefined; | |||
| // authentication (JWT) required | |||
| localVarCredential = this.configuration.lookupCredential('JWT'); | |||
| if (localVarCredential) { | |||
| localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential); | |||
| } | |||
| let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; | |||
| if (localVarHttpHeaderAcceptSelected === undefined) { | |||
| // to determine the Accept header | |||
| const httpHeaderAccepts: string[] = [ | |||
| 'application/ld+json', | |||
| 'application/problem+json', | |||
| 'application/json' | |||
| ]; | |||
| localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); | |||
| } | |||
| if (localVarHttpHeaderAcceptSelected !== undefined) { | |||
| localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); | |||
| } | |||
| let localVarHttpContext: HttpContext | undefined = options && options.context; | |||
| if (localVarHttpContext === undefined) { | |||
| localVarHttpContext = new HttpContext(); | |||
| } | |||
| let localVarTransferCache: boolean | undefined = options && options.transferCache; | |||
| if (localVarTransferCache === undefined) { | |||
| localVarTransferCache = true; | |||
| } | |||
| let responseType_: 'text' | 'json' | 'blob' = 'json'; | |||
| if (localVarHttpHeaderAcceptSelected) { | |||
| if (localVarHttpHeaderAcceptSelected.startsWith('text')) { | |||
| responseType_ = 'text'; | |||
| } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { | |||
| responseType_ = 'json'; | |||
| } else { | |||
| responseType_ = 'blob'; | |||
| } | |||
| } | |||
| let localVarPath = `/api/user_zones/${this.configuration.encodeParam({name: "id", value: id, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; | |||
| return this.httpClient.request<any>('delete', `${this.configuration.basePath}${localVarPath}`, | |||
| { | |||
| context: localVarHttpContext, | |||
| responseType: <any>responseType_, | |||
| withCredentials: this.configuration.withCredentials, | |||
| headers: localVarHeaders, | |||
| observe: observe, | |||
| transferCache: localVarTransferCache, | |||
| reportProgress: reportProgress | |||
| } | |||
| ); | |||
| } | |||
| /** | |||
| * Retrieves a UserZone resource. | |||
| * Retrieves a UserZone resource. | |||
| * @param id UserZone identifier | |||
| * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. | |||
| * @param reportProgress flag to report request and response progress. | |||
| */ | |||
| public userZonesIdGet(id: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/ld+json' | 'application/problem+json' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<UserZoneJsonld>; | |||
| public userZonesIdGet(id: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/ld+json' | 'application/problem+json' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<HttpResponse<UserZoneJsonld>>; | |||
| public userZonesIdGet(id: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/ld+json' | 'application/problem+json' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<HttpEvent<UserZoneJsonld>>; | |||
| public userZonesIdGet(id: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/ld+json' | 'application/problem+json' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<any> { | |||
| if (id === null || id === undefined) { | |||
| throw new Error('Required parameter id was null or undefined when calling userZonesIdGet.'); | |||
| } | |||
| let localVarHeaders = this.defaultHeaders; | |||
| let localVarCredential: string | undefined; | |||
| // authentication (JWT) required | |||
| localVarCredential = this.configuration.lookupCredential('JWT'); | |||
| if (localVarCredential) { | |||
| localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential); | |||
| } | |||
| let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; | |||
| if (localVarHttpHeaderAcceptSelected === undefined) { | |||
| // to determine the Accept header | |||
| const httpHeaderAccepts: string[] = [ | |||
| 'application/ld+json', | |||
| 'application/problem+json', | |||
| 'application/json' | |||
| ]; | |||
| localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); | |||
| } | |||
| if (localVarHttpHeaderAcceptSelected !== undefined) { | |||
| localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); | |||
| } | |||
| let localVarHttpContext: HttpContext | undefined = options && options.context; | |||
| if (localVarHttpContext === undefined) { | |||
| localVarHttpContext = new HttpContext(); | |||
| } | |||
| let localVarTransferCache: boolean | undefined = options && options.transferCache; | |||
| if (localVarTransferCache === undefined) { | |||
| localVarTransferCache = true; | |||
| } | |||
| let responseType_: 'text' | 'json' | 'blob' = 'json'; | |||
| if (localVarHttpHeaderAcceptSelected) { | |||
| if (localVarHttpHeaderAcceptSelected.startsWith('text')) { | |||
| responseType_ = 'text'; | |||
| } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { | |||
| responseType_ = 'json'; | |||
| } else { | |||
| responseType_ = 'blob'; | |||
| } | |||
| } | |||
| let localVarPath = `/api/user_zones/${this.configuration.encodeParam({name: "id", value: id, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; | |||
| return this.httpClient.request<UserZoneJsonld>('get', `${this.configuration.basePath}${localVarPath}`, | |||
| { | |||
| context: localVarHttpContext, | |||
| responseType: <any>responseType_, | |||
| withCredentials: this.configuration.withCredentials, | |||
| headers: localVarHeaders, | |||
| observe: observe, | |||
| transferCache: localVarTransferCache, | |||
| reportProgress: reportProgress | |||
| } | |||
| ); | |||
| } | |||
| /** | |||
| * Updates the UserZone resource. | |||
| * Updates the UserZone resource. | |||
| * @param id UserZone identifier | |||
| * @param userZone The updated UserZone resource | |||
| * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. | |||
| * @param reportProgress flag to report request and response progress. | |||
| */ | |||
| public userZonesIdPatch(id: string, userZone: UserZone, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/ld+json' | 'application/problem+json' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<UserZoneJsonld>; | |||
| public userZonesIdPatch(id: string, userZone: UserZone, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/ld+json' | 'application/problem+json' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<HttpResponse<UserZoneJsonld>>; | |||
| public userZonesIdPatch(id: string, userZone: UserZone, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/ld+json' | 'application/problem+json' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<HttpEvent<UserZoneJsonld>>; | |||
| public userZonesIdPatch(id: string, userZone: UserZone, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/ld+json' | 'application/problem+json' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<any> { | |||
| if (id === null || id === undefined) { | |||
| throw new Error('Required parameter id was null or undefined when calling userZonesIdPatch.'); | |||
| } | |||
| if (userZone === null || userZone === undefined) { | |||
| throw new Error('Required parameter userZone was null or undefined when calling userZonesIdPatch.'); | |||
| } | |||
| let localVarHeaders = this.defaultHeaders; | |||
| let localVarCredential: string | undefined; | |||
| // authentication (JWT) required | |||
| localVarCredential = this.configuration.lookupCredential('JWT'); | |||
| if (localVarCredential) { | |||
| localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential); | |||
| } | |||
| let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; | |||
| if (localVarHttpHeaderAcceptSelected === undefined) { | |||
| // to determine the Accept header | |||
| const httpHeaderAccepts: string[] = [ | |||
| 'application/ld+json', | |||
| 'application/problem+json', | |||
| 'application/json' | |||
| ]; | |||
| localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); | |||
| } | |||
| if (localVarHttpHeaderAcceptSelected !== undefined) { | |||
| localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); | |||
| } | |||
| let localVarHttpContext: HttpContext | undefined = options && options.context; | |||
| if (localVarHttpContext === undefined) { | |||
| localVarHttpContext = new HttpContext(); | |||
| } | |||
| let localVarTransferCache: boolean | undefined = options && options.transferCache; | |||
| if (localVarTransferCache === undefined) { | |||
| localVarTransferCache = true; | |||
| } | |||
| // to determine the Content-Type header | |||
| const consumes: string[] = [ | |||
| 'application/merge-patch+json' | |||
| ]; | |||
| const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes); | |||
| if (httpContentTypeSelected !== undefined) { | |||
| localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected); | |||
| } | |||
| let responseType_: 'text' | 'json' | 'blob' = 'json'; | |||
| if (localVarHttpHeaderAcceptSelected) { | |||
| if (localVarHttpHeaderAcceptSelected.startsWith('text')) { | |||
| responseType_ = 'text'; | |||
| } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { | |||
| responseType_ = 'json'; | |||
| } else { | |||
| responseType_ = 'blob'; | |||
| } | |||
| } | |||
| let localVarPath = `/api/user_zones/${this.configuration.encodeParam({name: "id", value: id, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; | |||
| return this.httpClient.request<UserZoneJsonld>('patch', `${this.configuration.basePath}${localVarPath}`, | |||
| { | |||
| context: localVarHttpContext, | |||
| body: userZone, | |||
| responseType: <any>responseType_, | |||
| withCredentials: this.configuration.withCredentials, | |||
| headers: localVarHeaders, | |||
| observe: observe, | |||
| transferCache: localVarTransferCache, | |||
| reportProgress: reportProgress | |||
| } | |||
| ); | |||
| } | |||
| /** | |||
| * Creates a UserZone resource. | |||
| * Creates a UserZone resource. | |||
| * @param userZoneJsonld The new UserZone resource | |||
| * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. | |||
| * @param reportProgress flag to report request and response progress. | |||
| */ | |||
| public userZonesPost(userZoneJsonld: UserZoneJsonld, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/ld+json' | 'application/problem+json' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<UserZoneJsonld>; | |||
| public userZonesPost(userZoneJsonld: UserZoneJsonld, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/ld+json' | 'application/problem+json' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<HttpResponse<UserZoneJsonld>>; | |||
| public userZonesPost(userZoneJsonld: UserZoneJsonld, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/ld+json' | 'application/problem+json' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<HttpEvent<UserZoneJsonld>>; | |||
| public userZonesPost(userZoneJsonld: UserZoneJsonld, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/ld+json' | 'application/problem+json' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<any> { | |||
| if (userZoneJsonld === null || userZoneJsonld === undefined) { | |||
| throw new Error('Required parameter userZoneJsonld was null or undefined when calling userZonesPost.'); | |||
| } | |||
| let localVarHeaders = this.defaultHeaders; | |||
| let localVarCredential: string | undefined; | |||
| // authentication (JWT) required | |||
| localVarCredential = this.configuration.lookupCredential('JWT'); | |||
| if (localVarCredential) { | |||
| localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential); | |||
| } | |||
| let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; | |||
| if (localVarHttpHeaderAcceptSelected === undefined) { | |||
| // to determine the Accept header | |||
| const httpHeaderAccepts: string[] = [ | |||
| 'application/ld+json', | |||
| 'application/problem+json', | |||
| 'application/json' | |||
| ]; | |||
| localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); | |||
| } | |||
| if (localVarHttpHeaderAcceptSelected !== undefined) { | |||
| localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); | |||
| } | |||
| let localVarHttpContext: HttpContext | undefined = options && options.context; | |||
| if (localVarHttpContext === undefined) { | |||
| localVarHttpContext = new HttpContext(); | |||
| } | |||
| let localVarTransferCache: boolean | undefined = options && options.transferCache; | |||
| if (localVarTransferCache === undefined) { | |||
| localVarTransferCache = true; | |||
| } | |||
| // to determine the Content-Type header | |||
| const consumes: string[] = [ | |||
| 'application/ld+json' | |||
| ]; | |||
| const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes); | |||
| if (httpContentTypeSelected !== undefined) { | |||
| localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected); | |||
| } | |||
| let responseType_: 'text' | 'json' | 'blob' = 'json'; | |||
| if (localVarHttpHeaderAcceptSelected) { | |||
| if (localVarHttpHeaderAcceptSelected.startsWith('text')) { | |||
| responseType_ = 'text'; | |||
| } else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) { | |||
| responseType_ = 'json'; | |||
| } else { | |||
| responseType_ = 'blob'; | |||
| } | |||
| } | |||
| let localVarPath = `/api/user_zones`; | |||
| return this.httpClient.request<UserZoneJsonld>('post', `${this.configuration.basePath}${localVarPath}`, | |||
| { | |||
| context: localVarHttpContext, | |||
| body: userZoneJsonld, | |||
| responseType: <any>responseType_, | |||
| withCredentials: this.configuration.withCredentials, | |||
| headers: localVarHeaders, | |||
| observe: observe, | |||
| transferCache: localVarTransferCache, | |||
| reportProgress: reportProgress | |||
| } | |||
| ); | |||
| } | |||
| } | |||
| @@ -0,0 +1,23 @@ | |||
| /** | |||
| * Imaq Platform | |||
| * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) | |||
| * | |||
| * The version of the OpenAPI document: 1.0.0 | |||
| * | |||
| * | |||
| * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). | |||
| * https://openapi-generator.tech | |||
| * Do not edit the class manually. | |||
| */ | |||
| import { UserZoneJsonld } from './userZoneJsonld'; | |||
| import { ApiEventsGetCollection200ResponseSearch } from './apiEventsGetCollection200ResponseSearch'; | |||
| import { ApiEventsGetCollection200ResponseView } from './apiEventsGetCollection200ResponseView'; | |||
| export interface ApiUserZonesGetCollection200Response { | |||
| member: Array<UserZoneJsonld>; | |||
| totalItems?: number; | |||
| view?: ApiEventsGetCollection200ResponseView; | |||
| search?: ApiEventsGetCollection200ResponseSearch; | |||
| } | |||
| @@ -9,6 +9,7 @@ export * from './apiTripLocationsGetCollection200Response'; | |||
| export * from './apiTripsGetCollection200Response'; | |||
| export * from './apiUserTripEventsGetCollection200Response'; | |||
| export * from './apiUserTripsGetCollection200Response'; | |||
| export * from './apiUserZonesGetCollection200Response'; | |||
| export * from './apiUsersGetCollection200Response'; | |||
| export * from './apiVesselsGetCollection200Response'; | |||
| export * from './apiZonesGetCollection200Response'; | |||
| @@ -37,6 +38,8 @@ export * from './userTrip'; | |||
| export * from './userTripEvent'; | |||
| export * from './userTripEventJsonld'; | |||
| export * from './userTripJsonld'; | |||
| export * from './userZone'; | |||
| export * from './userZoneJsonld'; | |||
| export * from './vessel'; | |||
| export * from './vesselJsonld'; | |||
| export * from './zone'; | |||
| @@ -0,0 +1,24 @@ | |||
| /** | |||
| * Imaq Platform | |||
| * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) | |||
| * | |||
| * The version of the OpenAPI document: 1.0.0 | |||
| * | |||
| * | |||
| * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). | |||
| * https://openapi-generator.tech | |||
| * Do not edit the class manually. | |||
| */ | |||
| /** | |||
| * | |||
| */ | |||
| export interface UserZone { | |||
| readonly dbId?: number | null; | |||
| readonly user?: string; | |||
| userIri?: string | null; | |||
| readonly zone?: string; | |||
| zoneIri?: string | null; | |||
| } | |||
| @@ -0,0 +1,29 @@ | |||
| /** | |||
| * Imaq Platform | |||
| * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) | |||
| * | |||
| * The version of the OpenAPI document: 1.0.0 | |||
| * | |||
| * | |||
| * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). | |||
| * https://openapi-generator.tech | |||
| * Do not edit the class manually. | |||
| */ | |||
| import { UserJsonld } from './userJsonld'; | |||
| import { ConstraintViolationJsonldJsonldContext } from './constraintViolationJsonldJsonldContext'; | |||
| import { ZoneJsonld } from './zoneJsonld'; | |||
| /** | |||
| * | |||
| */ | |||
| export interface UserZoneJsonld { | |||
| readonly id?: string; | |||
| readonly xType?: string; | |||
| readonly dbId?: number | null; | |||
| readonly user?: UserJsonld; | |||
| userIri?: string | null; | |||
| readonly zone?: ZoneJsonld; | |||
| zoneIri?: string | null; | |||
| } | |||
| @@ -4,7 +4,8 @@ | |||
| "shipping_companies": "Shipping companies", | |||
| "vessels": "Vessels", | |||
| "view": "Base data", | |||
| "zones": "Zones" | |||
| "zones": "Zones", | |||
| "pilot": "Pilot" | |||
| }, | |||
| "basic": { | |||
| "account": "Account", | |||
| @@ -76,6 +77,8 @@ | |||
| "user": "User", | |||
| "user_trip": "Pilotage", | |||
| "user_trip_event": "Pilotage event", | |||
| "user_zone": "User zone", | |||
| "user_zones": "User zones", | |||
| "vessel": "Vessel", | |||
| "zone": "Zone" | |||
| }, | |||
| @@ -0,0 +1,35 @@ | |||
| <?php | |||
| declare(strict_types=1); | |||
| namespace DoctrineMigrations; | |||
| use Doctrine\DBAL\Schema\Schema; | |||
| use Doctrine\Migrations\AbstractMigration; | |||
| /** | |||
| * Auto-generated Migration: Please modify to your needs! | |||
| */ | |||
| final class Version20250605145642 extends AbstractMigration | |||
| { | |||
| public function getDescription(): string | |||
| { | |||
| return ''; | |||
| } | |||
| public function up(Schema $schema): void | |||
| { | |||
| // this up() migration is auto-generated, please modify it to your needs | |||
| $this->addSql('CREATE TABLE user_zone (id INT AUTO_INCREMENT NOT NULL, user_id INT NOT NULL, zone_id INT NOT NULL, INDEX IDX_DA6A8CCEA76ED395 (user_id), INDEX IDX_DA6A8CCE9F2C3FAB (zone_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); | |||
| $this->addSql('ALTER TABLE user_zone ADD CONSTRAINT FK_DA6A8CCEA76ED395 FOREIGN KEY (user_id) REFERENCES `user` (id) ON DELETE CASCADE'); | |||
| $this->addSql('ALTER TABLE user_zone ADD CONSTRAINT FK_DA6A8CCE9F2C3FAB FOREIGN KEY (zone_id) REFERENCES zone (id) ON DELETE CASCADE'); | |||
| } | |||
| public function down(Schema $schema): void | |||
| { | |||
| // this down() migration is auto-generated, please modify it to your needs | |||
| $this->addSql('ALTER TABLE user_zone DROP FOREIGN KEY FK_DA6A8CCEA76ED395'); | |||
| $this->addSql('ALTER TABLE user_zone DROP FOREIGN KEY FK_DA6A8CCE9F2C3FAB'); | |||
| $this->addSql('DROP TABLE user_zone'); | |||
| } | |||
| } | |||
| @@ -0,0 +1,31 @@ | |||
| <?php | |||
| declare(strict_types=1); | |||
| namespace DoctrineMigrations; | |||
| use Doctrine\DBAL\Schema\Schema; | |||
| use Doctrine\Migrations\AbstractMigration; | |||
| /** | |||
| * Auto-generated Migration: Please modify to your needs! | |||
| */ | |||
| final class Version20250606081404 extends AbstractMigration | |||
| { | |||
| public function getDescription(): string | |||
| { | |||
| return ''; | |||
| } | |||
| public function up(Schema $schema): void | |||
| { | |||
| // this up() migration is auto-generated, please modify it to your needs | |||
| $this->addSql('CREATE UNIQUE INDEX unique_user_zone ON user_zone (zone_id, user_id)'); | |||
| } | |||
| public function down(Schema $schema): void | |||
| { | |||
| // this down() migration is auto-generated, please modify it to your needs | |||
| $this->addSql('DROP INDEX unique_user_zone ON user_zone'); | |||
| } | |||
| } | |||
| @@ -0,0 +1,78 @@ | |||
| <?php | |||
| namespace App\ApiResource; | |||
| use ApiPlatform\Doctrine\Orm\Filter\SearchFilter; | |||
| use ApiPlatform\Doctrine\Orm\State\Options; | |||
| use ApiPlatform\Metadata\ApiFilter; | |||
| use ApiPlatform\Metadata\ApiProperty; | |||
| use ApiPlatform\Metadata\ApiResource; | |||
| use ApiPlatform\Metadata\Delete; | |||
| use ApiPlatform\Metadata\Get; | |||
| use ApiPlatform\Metadata\GetCollection; | |||
| use ApiPlatform\Metadata\Patch; | |||
| use ApiPlatform\Metadata\Post; | |||
| use App\Entity\UserZone; | |||
| use App\Filter\CustomJsonFilter; | |||
| use App\Filter\CustomJsonOrderFilter; | |||
| use App\State\EntityClassDtoStateProcessor; | |||
| use App\State\EntityToDtoStateProvider; | |||
| use Symfony\Component\PropertyInfo\Type; | |||
| #[ApiResource( | |||
| shortName: 'UserZone', | |||
| operations: [ | |||
| new Get(security: 'is_granted("ROLE_USER")'), | |||
| new GetCollection(security: 'is_granted("ROLE_USER")'), | |||
| new Post(security: 'is_granted("ROLE_ADMIN")'), | |||
| new Patch(security: 'is_granted("ROLE_ADMIN")'), | |||
| new Delete(security: 'is_granted("ROLE_ADMIN")') | |||
| ], | |||
| security: 'is_granted("ROLE_USER")', | |||
| provider: EntityToDtoStateProvider::class, | |||
| processor: EntityClassDtoStateProcessor::class, | |||
| stateOptions: new Options(entityClass: UserZone::class), | |||
| )] | |||
| #[ApiFilter(SearchFilter::class, properties: [ | |||
| 'user' => 'exact', | |||
| 'zone' => 'exact', | |||
| ])] | |||
| #[ApiFilter(CustomJsonFilter::class)] | |||
| #[ApiFilter(CustomJsonOrderFilter::class)] | |||
| class UserZoneApi | |||
| { | |||
| #[ApiProperty(readable: false, writable: false, identifier: true)] | |||
| public ?int $id = null; | |||
| #[ApiProperty(writable: false)] | |||
| public ?int $dbId = null; | |||
| /** | |||
| * @var UserApi | |||
| */ | |||
| #[ApiProperty( | |||
| writable: false, | |||
| readableLink: true, | |||
| writableLink: false, | |||
| builtinTypes: [new Type('object', class: UserApi::class)] | |||
| )] | |||
| public ?UserApi $user = null; | |||
| #[ApiProperty(writable: true)] | |||
| public ?UserApi $userIri = null; | |||
| /** | |||
| * @var ZoneApi | |||
| */ | |||
| #[ApiProperty( | |||
| writable: false, | |||
| readableLink: true, | |||
| writableLink: false, | |||
| builtinTypes: [new Type('object', class: ZoneApi::class)] | |||
| )] | |||
| public ?ZoneApi $zone = null; | |||
| #[ApiProperty(writable: true)] | |||
| public ?ZoneApi $zoneIri = null; | |||
| } | |||
| @@ -0,0 +1,47 @@ | |||
| <?php | |||
| namespace App\Entity; | |||
| use App\Repository\UserZoneRepository; | |||
| use Doctrine\ORM\Mapping as ORM; | |||
| #[ORM\Entity(repositoryClass: UserZoneRepository::class)] | |||
| #[ORM\UniqueConstraint(name: "unique_user_zone", columns: ["zone_id", "user_id"])] | |||
| class UserZone | |||
| { | |||
| #[ORM\Id, ORM\GeneratedValue, ORM\Column(type: 'integer')] | |||
| private int $id; | |||
| #[ORM\ManyToOne] | |||
| #[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')] | |||
| private ?User $user = null; | |||
| #[ORM\ManyToOne] | |||
| #[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')] | |||
| private ?Zone $zone = null; | |||
| public function getId(): int | |||
| { | |||
| return $this->id; | |||
| } | |||
| public function getUser(): ?User | |||
| { | |||
| return $this->user; | |||
| } | |||
| public function setUser(?User $user): void | |||
| { | |||
| $this->user = $user; | |||
| } | |||
| public function getZone(): ?Zone | |||
| { | |||
| return $this->zone; | |||
| } | |||
| public function setZone(?Zone $zone): void | |||
| { | |||
| $this->zone = $zone; | |||
| } | |||
| } | |||
| @@ -0,0 +1,58 @@ | |||
| <?php | |||
| namespace App\Mapper; | |||
| use App\ApiResource\UserZoneApi; | |||
| use App\Entity\UserZone; | |||
| use App\Repository\UserRepository; | |||
| use App\Repository\UserZoneRepository; | |||
| use App\Repository\ZoneRepository; | |||
| use Symfonycasts\MicroMapper\AsMapper; | |||
| use Symfonycasts\MicroMapper\MapperInterface; | |||
| #[AsMapper(from: UserZoneApi::class, to: UserZone::class)] | |||
| class UserZoneApiToEntityMapper implements MapperInterface | |||
| { | |||
| public function __construct( | |||
| private readonly UserZoneRepository $userZoneRepository, | |||
| private readonly UserRepository $userRepository, | |||
| private readonly ZoneRepository $zoneRepository | |||
| ) {} | |||
| public function load(object $from, string $toClass, array $context): object | |||
| { | |||
| $dto = $from; | |||
| assert($dto instanceof UserZoneApi); | |||
| $entity = $dto->id ? $this->userZoneRepository->find($dto->id) : new UserZone(); | |||
| if ($dto->id && !$entity) { | |||
| throw new \Exception('UserZone not found'); | |||
| } | |||
| return $entity; | |||
| } | |||
| public function populate(object $from, object $to, array $context): object | |||
| { | |||
| assert($from instanceof UserZoneApi); | |||
| assert($to instanceof UserZone); | |||
| if ($from->userIri) { | |||
| $user = $this->userRepository->find($from->userIri->id); | |||
| if (!$user) { | |||
| throw new \Exception('User not found'); | |||
| } | |||
| $to->setUser($user); | |||
| } | |||
| if ($from->zoneIri) { | |||
| $zone = $this->zoneRepository->find($from->zoneIri->id); | |||
| if (!$zone) { | |||
| throw new \Exception('Zone not found'); | |||
| } | |||
| $to->setZone($zone); | |||
| } | |||
| return $to; | |||
| } | |||
| } | |||
| @@ -0,0 +1,48 @@ | |||
| <?php | |||
| namespace App\Mapper; | |||
| use App\ApiResource\UserApi; | |||
| use App\ApiResource\UserZoneApi; | |||
| use App\ApiResource\ZoneApi; | |||
| use App\Entity\UserZone; | |||
| use Symfonycasts\MicroMapper\AsMapper; | |||
| use Symfonycasts\MicroMapper\MapperInterface; | |||
| use Symfonycasts\MicroMapper\MicroMapperInterface; | |||
| #[AsMapper(from: UserZone::class, to: UserZoneApi::class)] | |||
| class UserZoneEntityToApiMapper implements MapperInterface | |||
| { | |||
| public function __construct( | |||
| private readonly MicroMapperInterface $microMapper | |||
| ) {} | |||
| public function load(object $from, string $toClass, array $context): object | |||
| { | |||
| $entity = $from; | |||
| assert($entity instanceof UserZone); | |||
| $dto = new UserZoneApi(); | |||
| $dto->id = $entity->getId(); | |||
| return $dto; | |||
| } | |||
| public function populate(object $from, object $to, array $context): object | |||
| { | |||
| assert($from instanceof UserZone); | |||
| assert($to instanceof UserZoneApi); | |||
| $to->dbId = $from->getId(); | |||
| $to->user = $to->userIri = $this->microMapper->map($from->getUser(), UserApi::class, [ | |||
| MicroMapperInterface::MAX_DEPTH => 5, | |||
| ]); | |||
| $to->zone = $to->zoneIri = $this->microMapper->map($from->getZone(), ZoneApi::class, [ | |||
| MicroMapperInterface::MAX_DEPTH => 5, | |||
| ]); | |||
| return $to; | |||
| } | |||
| } | |||
| @@ -0,0 +1,15 @@ | |||
| <?php | |||
| namespace App\Repository; | |||
| use App\Entity\UserZone; | |||
| use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; | |||
| use Doctrine\Persistence\ManagerRegistry; | |||
| class UserZoneRepository extends ServiceEntityRepository | |||
| { | |||
| public function __construct(ManagerRegistry $registry) | |||
| { | |||
| parent::__construct($registry, UserZone::class); | |||
| } | |||
| } | |||