| @@ -1937,6 +1937,18 @@ paths: | |||||
| style: form | style: form | ||||
| explode: false | explode: false | ||||
| allowReserved: false | 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 | name: custom_json_order | ||||
| in: query | in: query | ||||
| @@ -3947,6 +3959,8 @@ components: | |||||
| type: boolean | type: boolean | ||||
| isPort: | isPort: | ||||
| type: boolean | type: boolean | ||||
| isStartEnd: | |||||
| type: boolean | |||||
| createdAt: | createdAt: | ||||
| readOnly: true | readOnly: true | ||||
| type: | type: | ||||
| @@ -4012,6 +4026,8 @@ components: | |||||
| type: boolean | type: boolean | ||||
| isPort: | isPort: | ||||
| type: boolean | type: boolean | ||||
| isStartEnd: | |||||
| type: boolean | |||||
| createdAt: | createdAt: | ||||
| readOnly: true | readOnly: true | ||||
| type: | type: | ||||
| @@ -4171,10 +4187,6 @@ components: | |||||
| type: | type: | ||||
| - string | - string | ||||
| - 'null' | - 'null' | ||||
| captainName: | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| startLocation: | startLocation: | ||||
| readOnly: true | readOnly: true | ||||
| type: string | type: string | ||||
| @@ -4207,6 +4219,8 @@ components: | |||||
| type: | type: | ||||
| - string | - string | ||||
| - 'null' | - 'null' | ||||
| completed: | |||||
| type: boolean | |||||
| createdAt: | createdAt: | ||||
| readOnly: true | readOnly: true | ||||
| type: | type: | ||||
| @@ -4270,10 +4284,6 @@ components: | |||||
| type: | type: | ||||
| - string | - string | ||||
| - 'null' | - 'null' | ||||
| captainName: | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| startLocation: | startLocation: | ||||
| readOnly: true | readOnly: true | ||||
| $ref: '#/components/schemas/Location.jsonld' | $ref: '#/components/schemas/Location.jsonld' | ||||
| @@ -4302,6 +4312,8 @@ components: | |||||
| type: | type: | ||||
| - string | - string | ||||
| - 'null' | - 'null' | ||||
| completed: | |||||
| type: boolean | |||||
| createdAt: | createdAt: | ||||
| readOnly: true | readOnly: true | ||||
| type: | type: | ||||
| @@ -4342,6 +4354,10 @@ components: | |||||
| example: 'https://example.com/' | example: 'https://example.com/' | ||||
| isArrival: | isArrival: | ||||
| type: boolean | type: boolean | ||||
| isTransit: | |||||
| type: boolean | |||||
| isDeparture: | |||||
| type: boolean | |||||
| date: | date: | ||||
| type: string | type: string | ||||
| format: date-time | format: date-time | ||||
| @@ -4406,6 +4422,10 @@ components: | |||||
| example: 'https://example.com/' | example: 'https://example.com/' | ||||
| isArrival: | isArrival: | ||||
| type: boolean | type: boolean | ||||
| isTransit: | |||||
| type: boolean | |||||
| isDeparture: | |||||
| type: boolean | |||||
| date: | date: | ||||
| type: string | type: string | ||||
| format: date-time | format: date-time | ||||
| @@ -4471,6 +4491,8 @@ components: | |||||
| type: boolean | type: boolean | ||||
| active: | active: | ||||
| type: boolean | type: boolean | ||||
| isPilot: | |||||
| type: boolean | |||||
| roles: | roles: | ||||
| readOnly: true | readOnly: true | ||||
| type: array | type: array | ||||
| @@ -4489,6 +4511,7 @@ components: | |||||
| - lastName | - lastName | ||||
| - isAdmin | - isAdmin | ||||
| - active | - active | ||||
| - isPilot | |||||
| User.jsonld: | User.jsonld: | ||||
| type: object | type: object | ||||
| description: '' | description: '' | ||||
| @@ -4562,6 +4585,8 @@ components: | |||||
| type: boolean | type: boolean | ||||
| active: | active: | ||||
| type: boolean | type: boolean | ||||
| isPilot: | |||||
| type: boolean | |||||
| roles: | roles: | ||||
| readOnly: true | readOnly: true | ||||
| type: array | type: array | ||||
| @@ -4580,6 +4605,7 @@ components: | |||||
| - lastName | - lastName | ||||
| - isAdmin | - isAdmin | ||||
| - active | - active | ||||
| - isPilot | |||||
| UserTrip: | UserTrip: | ||||
| type: object | type: object | ||||
| description: '' | description: '' | ||||
| @@ -4618,6 +4644,8 @@ components: | |||||
| - 'null' | - 'null' | ||||
| completed: | completed: | ||||
| type: boolean | type: boolean | ||||
| approved: | |||||
| type: boolean | |||||
| signature: | signature: | ||||
| readOnly: true | readOnly: true | ||||
| type: string | type: string | ||||
| @@ -4649,6 +4677,7 @@ components: | |||||
| - tripIri | - tripIri | ||||
| - userIri | - userIri | ||||
| - completed | - completed | ||||
| - approved | |||||
| UserTrip.jsonld: | UserTrip.jsonld: | ||||
| type: object | type: object | ||||
| description: '' | description: '' | ||||
| @@ -4706,6 +4735,8 @@ components: | |||||
| - 'null' | - 'null' | ||||
| completed: | completed: | ||||
| type: boolean | type: boolean | ||||
| approved: | |||||
| type: boolean | |||||
| signature: | signature: | ||||
| readOnly: true | readOnly: true | ||||
| $ref: '#/components/schemas/MediaObject.jsonld' | $ref: '#/components/schemas/MediaObject.jsonld' | ||||
| @@ -4735,6 +4766,7 @@ components: | |||||
| - tripIri | - tripIri | ||||
| - userIri | - userIri | ||||
| - completed | - completed | ||||
| - approved | |||||
| UserTripEvent: | UserTripEvent: | ||||
| type: object | type: object | ||||
| description: '' | description: '' | ||||
| @@ -4905,6 +4937,30 @@ components: | |||||
| - 'null' | - 'null' | ||||
| format: iri-reference | format: iri-reference | ||||
| example: 'https://example.com/' | example: 'https://example.com/' | ||||
| length: | |||||
| type: | |||||
| - number | |||||
| - 'null' | |||||
| breadth: | |||||
| type: | |||||
| - number | |||||
| - 'null' | |||||
| draft: | |||||
| type: | |||||
| - number | |||||
| - 'null' | |||||
| grossTonnage: | |||||
| type: | |||||
| - number | |||||
| - 'null' | |||||
| imoNo: | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| callSign: | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| createdAt: | createdAt: | ||||
| readOnly: true | readOnly: true | ||||
| type: | type: | ||||
| @@ -4961,6 +5017,30 @@ components: | |||||
| - 'null' | - 'null' | ||||
| format: iri-reference | format: iri-reference | ||||
| example: 'https://example.com/' | example: 'https://example.com/' | ||||
| length: | |||||
| type: | |||||
| - number | |||||
| - 'null' | |||||
| breadth: | |||||
| type: | |||||
| - number | |||||
| - 'null' | |||||
| draft: | |||||
| type: | |||||
| - number | |||||
| - 'null' | |||||
| grossTonnage: | |||||
| type: | |||||
| - number | |||||
| - 'null' | |||||
| imoNo: | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| callSign: | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| createdAt: | createdAt: | ||||
| readOnly: true | readOnly: true | ||||
| type: | type: | ||||
| @@ -88,7 +88,7 @@ export abstract class AbstractDataFormComponent<T extends { [key: string]: any } | |||||
| return; | return; | ||||
| } | } | ||||
| this.translateService.get('basic.delete_confirm').subscribe((confirmMessage: string) => { | |||||
| this.translateService.get('basic.delete_confirm_related').subscribe((confirmMessage: string) => { | |||||
| if (confirm(confirmMessage)) { | if (confirm(confirmMessage)) { | ||||
| this.deleteFn!(this.id!).subscribe({ | this.deleteFn!(this.id!).subscribe({ | ||||
| next: () => { | next: () => { | ||||
| @@ -124,6 +124,46 @@ export class SearchSelectComponent implements OnInit, AfterViewInit { | |||||
| sortable: true, | sortable: true, | ||||
| filterType: FilterBarComponent.FILTER_TYPE_TEXT, | filterType: FilterBarComponent.FILTER_TYPE_TEXT, | ||||
| } as ListColDefinition, | } as ListColDefinition, | ||||
| { | |||||
| name: 'is_zone', | |||||
| text: 'location.is_zone', | |||||
| type: ListComponent.COLUMN_TYPE_BOOLEAN, | |||||
| field: 'isZone', | |||||
| sortable: true, | |||||
| filterType: FilterBarComponent.FILTER_TYPE_BOOLEAN, | |||||
| } as ListColDefinition, | |||||
| { | |||||
| name: 'is_place', | |||||
| text: 'location.is_place', | |||||
| type: ListComponent.COLUMN_TYPE_BOOLEAN, | |||||
| field: 'isPlace', | |||||
| sortable: true, | |||||
| filterType: FilterBarComponent.FILTER_TYPE_BOOLEAN, | |||||
| } as ListColDefinition, | |||||
| { | |||||
| name: 'is_port', | |||||
| text: 'location.is_port', | |||||
| type: ListComponent.COLUMN_TYPE_BOOLEAN, | |||||
| field: 'isPort', | |||||
| sortable: true, | |||||
| filterType: FilterBarComponent.FILTER_TYPE_BOOLEAN, | |||||
| } as ListColDefinition, | |||||
| { | |||||
| name: 'is_start_end', | |||||
| text: 'location.is_start_end', | |||||
| type: ListComponent.COLUMN_TYPE_BOOLEAN, | |||||
| field: 'isStartEnd', | |||||
| sortable: true, | |||||
| filterType: FilterBarComponent.FILTER_TYPE_BOOLEAN, | |||||
| } as ListColDefinition, | |||||
| { | |||||
| name: 'createdAt', | |||||
| text: 'common.created_at', | |||||
| type: ListComponent.COLUMN_TYPE_DATE, | |||||
| field: 'createdAt', | |||||
| sortable: true, | |||||
| filterType: FilterBarComponent.FILTER_TYPE_DATE, | |||||
| } as ListColDefinition, | |||||
| ]; | ]; | ||||
| } | } | ||||
| @@ -204,6 +244,54 @@ export class SearchSelectComponent implements OnInit, AfterViewInit { | |||||
| sortable: true, | sortable: true, | ||||
| filterType: FilterBarComponent.FILTER_TYPE_TEXT, | filterType: FilterBarComponent.FILTER_TYPE_TEXT, | ||||
| } as ListColDefinition, | } as ListColDefinition, | ||||
| { | |||||
| name: 'length', | |||||
| text: 'vessel.length', | |||||
| type: ListComponent.COLUMN_TYPE_NUMBER, | |||||
| field: 'length', | |||||
| sortable: true, | |||||
| filterType: FilterBarComponent.FILTER_TYPE_NUMBER, | |||||
| } as ListColDefinition, | |||||
| { | |||||
| name: 'breadth', | |||||
| text: 'vessel.breadth', | |||||
| type: ListComponent.COLUMN_TYPE_NUMBER, | |||||
| field: 'breadth', | |||||
| sortable: true, | |||||
| filterType: FilterBarComponent.FILTER_TYPE_NUMBER, | |||||
| } as ListColDefinition, | |||||
| { | |||||
| name: 'draft', | |||||
| text: 'vessel.draft', | |||||
| type: ListComponent.COLUMN_TYPE_NUMBER, | |||||
| field: 'draft', | |||||
| sortable: true, | |||||
| filterType: FilterBarComponent.FILTER_TYPE_NUMBER, | |||||
| } as ListColDefinition, | |||||
| { | |||||
| name: 'grossTonnage', | |||||
| text: 'vessel.grossTonnage', | |||||
| type: ListComponent.COLUMN_TYPE_NUMBER, | |||||
| field: 'grossTonnage', | |||||
| sortable: true, | |||||
| filterType: FilterBarComponent.FILTER_TYPE_NUMBER, | |||||
| } as ListColDefinition, | |||||
| { | |||||
| name: 'imoNo', | |||||
| text: 'vessel.imoNo', | |||||
| type: ListComponent.COLUMN_TYPE_TEXT, | |||||
| field: 'imoNo', | |||||
| sortable: true, | |||||
| filterType: FilterBarComponent.FILTER_TYPE_TEXT, | |||||
| } as ListColDefinition, | |||||
| { | |||||
| name: 'callSign', | |||||
| text: 'vessel.callSign', | |||||
| type: ListComponent.COLUMN_TYPE_TEXT, | |||||
| field: 'callSign', | |||||
| sortable: true, | |||||
| filterType: FilterBarComponent.FILTER_TYPE_TEXT, | |||||
| } as ListColDefinition, | |||||
| { | { | ||||
| name: 'createdAt', | name: 'createdAt', | ||||
| text: 'common.created_at', | text: 'common.created_at', | ||||
| @@ -218,27 +306,61 @@ export class SearchSelectComponent implements OnInit, AfterViewInit { | |||||
| public static getDefaultColDefUsers(subResource?: string): ListColDefinition[] { | public static getDefaultColDefUsers(subResource?: string): ListColDefinition[] { | ||||
| return [ | return [ | ||||
| { | { | ||||
| name: 'fullName', | |||||
| text: 'users.full_name', | |||||
| name: 'image', | |||||
| text: 'basic.image', | |||||
| type: ListComponent.COLUMN_TYPE_IMAGE, | |||||
| field: 'imageUrl', | |||||
| } as ListColDefinition, | |||||
| { | |||||
| name: 'firstName', | |||||
| text: 'users.firstname', | |||||
| type: ListComponent.COLUMN_TYPE_TEXT, | type: ListComponent.COLUMN_TYPE_TEXT, | ||||
| field: 'fullName', | |||||
| field: 'firstName', | |||||
| sortable: true, | sortable: true, | ||||
| filterType: FilterBarComponent.FILTER_TYPE_TEXT, | |||||
| }, | |||||
| } as ListColDefinition, | |||||
| { | |||||
| name: 'lastName', | |||||
| text: 'users.lastname', | |||||
| type: ListComponent.COLUMN_TYPE_TEXT_BOLD, | |||||
| field: 'lastName', | |||||
| sortable: true, | |||||
| } as ListColDefinition, | |||||
| { | { | ||||
| name: 'email', | name: 'email', | ||||
| text: 'users.email', | text: 'users.email', | ||||
| type: ListComponent.COLUMN_TYPE_TEXT, | |||||
| type: ListComponent.COLUMN_TYPE_EMAIL, | |||||
| field: 'email', | field: 'email', | ||||
| sortable: true, | |||||
| filterType: FilterBarComponent.FILTER_TYPE_TEXT, | |||||
| }, | |||||
| } as ListColDefinition, | |||||
| { | { | ||||
| name: 'referenceId', | name: 'referenceId', | ||||
| text: 'users.pilotIdNo', | text: 'users.pilotIdNo', | ||||
| type: ListComponent.COLUMN_TYPE_TEXT_BOLD, | type: ListComponent.COLUMN_TYPE_TEXT_BOLD, | ||||
| field: 'referenceId', | field: 'referenceId', | ||||
| } as ListColDefinition, | } as ListColDefinition, | ||||
| { | |||||
| name: 'isAdmin', | |||||
| text: 'users.is_admin', | |||||
| type: ListComponent.COLUMN_TYPE_BOOLEAN, | |||||
| field: 'isAdmin', | |||||
| sortable: true, | |||||
| filterType: FilterBarComponent.FILTER_TYPE_BOOLEAN, | |||||
| } as ListColDefinition, | |||||
| { | |||||
| name: 'isPilot', | |||||
| text: 'users.is_pilot', | |||||
| type: ListComponent.COLUMN_TYPE_BOOLEAN, | |||||
| field: 'isPilot', | |||||
| sortable: true, | |||||
| filterType: FilterBarComponent.FILTER_TYPE_BOOLEAN, | |||||
| } as ListColDefinition, | |||||
| { | |||||
| name: 'active', | |||||
| text: 'users.active', | |||||
| type: ListComponent.COLUMN_TYPE_BOOLEAN, | |||||
| field: 'active', | |||||
| sortable: true, | |||||
| filterType: FilterBarComponent.FILTER_TYPE_BOOLEAN, | |||||
| } as ListColDefinition, | |||||
| ]; | ]; | ||||
| } | } | ||||
| @@ -55,6 +55,7 @@ export const locationForm = new FormGroup({ | |||||
| isZone: new FormControl(null, []), | isZone: new FormControl(null, []), | ||||
| isPlace: new FormControl(null, []), | isPlace: new FormControl(null, []), | ||||
| isPort: new FormControl(null, []), | isPort: new FormControl(null, []), | ||||
| isStartEnd: new FormControl(null, []), | |||||
| createdAt: new FormControl(null, []) | createdAt: new FormControl(null, []) | ||||
| }); | }); | ||||
| @@ -68,6 +69,7 @@ export const locationJsonldForm = new FormGroup({ | |||||
| isZone: new FormControl(null, []), | isZone: new FormControl(null, []), | ||||
| isPlace: new FormControl(null, []), | isPlace: new FormControl(null, []), | ||||
| isPort: new FormControl(null, []), | isPort: new FormControl(null, []), | ||||
| isStartEnd: new FormControl(null, []), | |||||
| createdAt: new FormControl(null, []) | createdAt: new FormControl(null, []) | ||||
| }); | }); | ||||
| @@ -98,7 +100,6 @@ export const tripForm = new FormGroup({ | |||||
| vesselIri: new FormControl(null, [Validators.required]), | vesselIri: new FormControl(null, [Validators.required]), | ||||
| pilotageReference: new FormControl(null, []), | pilotageReference: new FormControl(null, []), | ||||
| customerReference: new FormControl(null, []), | customerReference: new FormControl(null, []), | ||||
| captainName: new FormControl(null, []), | |||||
| startLocation: new FormControl(null, []), | startLocation: new FormControl(null, []), | ||||
| startLocationIri: new FormControl(null, [Validators.required]), | startLocationIri: new FormControl(null, [Validators.required]), | ||||
| endLocation: new FormControl(null, []), | endLocation: new FormControl(null, []), | ||||
| @@ -106,6 +107,7 @@ export const tripForm = new FormGroup({ | |||||
| startDate: new FormControl(null, [Validators.required]), | startDate: new FormControl(null, [Validators.required]), | ||||
| endDate: new FormControl(null, [Validators.required]), | endDate: new FormControl(null, [Validators.required]), | ||||
| note: new FormControl(null, []), | note: new FormControl(null, []), | ||||
| completed: new FormControl(null, []), | |||||
| createdAt: new FormControl(null, []) | createdAt: new FormControl(null, []) | ||||
| }); | }); | ||||
| @@ -115,7 +117,6 @@ export const tripJsonldForm = new FormGroup({ | |||||
| vesselIri: new FormControl(null, [Validators.required]), | vesselIri: new FormControl(null, [Validators.required]), | ||||
| pilotageReference: new FormControl(null, []), | pilotageReference: new FormControl(null, []), | ||||
| customerReference: new FormControl(null, []), | customerReference: new FormControl(null, []), | ||||
| captainName: new FormControl(null, []), | |||||
| startLocation: new FormControl(null, []), | startLocation: new FormControl(null, []), | ||||
| startLocationIri: new FormControl(null, [Validators.required]), | startLocationIri: new FormControl(null, [Validators.required]), | ||||
| endLocation: new FormControl(null, []), | endLocation: new FormControl(null, []), | ||||
| @@ -123,6 +124,7 @@ export const tripJsonldForm = new FormGroup({ | |||||
| startDate: new FormControl(null, [Validators.required]), | startDate: new FormControl(null, [Validators.required]), | ||||
| endDate: new FormControl(null, [Validators.required]), | endDate: new FormControl(null, [Validators.required]), | ||||
| note: new FormControl(null, []), | note: new FormControl(null, []), | ||||
| completed: new FormControl(null, []), | |||||
| createdAt: new FormControl(null, []) | createdAt: new FormControl(null, []) | ||||
| }); | }); | ||||
| @@ -133,6 +135,8 @@ export const tripLocationForm = new FormGroup({ | |||||
| location: new FormControl(null, []), | location: new FormControl(null, []), | ||||
| locationIri: new FormControl(null, [Validators.required]), | locationIri: new FormControl(null, [Validators.required]), | ||||
| isArrival: new FormControl(null, []), | isArrival: new FormControl(null, []), | ||||
| isTransit: new FormControl(null, []), | |||||
| isDeparture: new FormControl(null, []), | |||||
| date: new FormControl(null, [Validators.required]), | date: new FormControl(null, [Validators.required]), | ||||
| createdAt: new FormControl(null, []) | createdAt: new FormControl(null, []) | ||||
| }); | }); | ||||
| @@ -144,6 +148,8 @@ export const tripLocationJsonldForm = new FormGroup({ | |||||
| location: new FormControl(null, []), | location: new FormControl(null, []), | ||||
| locationIri: new FormControl(null, [Validators.required]), | locationIri: new FormControl(null, [Validators.required]), | ||||
| isArrival: new FormControl(null, []), | isArrival: new FormControl(null, []), | ||||
| isTransit: new FormControl(null, []), | |||||
| isDeparture: new FormControl(null, []), | |||||
| date: new FormControl(null, [Validators.required]), | date: new FormControl(null, [Validators.required]), | ||||
| createdAt: new FormControl(null, []) | createdAt: new FormControl(null, []) | ||||
| }); | }); | ||||
| @@ -161,6 +167,7 @@ export const userForm = new FormGroup({ | |||||
| password: new FormControl(null, []), | password: new FormControl(null, []), | ||||
| isAdmin: new FormControl(null, [Validators.required]), | isAdmin: new FormControl(null, [Validators.required]), | ||||
| active: new FormControl(null, [Validators.required]), | active: new FormControl(null, [Validators.required]), | ||||
| isPilot: new FormControl(null, [Validators.required]), | |||||
| roles: new FormControl(null, []), | roles: new FormControl(null, []), | ||||
| createdAt: new FormControl(null, []) | createdAt: new FormControl(null, []) | ||||
| }); | }); | ||||
| @@ -178,6 +185,7 @@ export const userJsonldForm = new FormGroup({ | |||||
| password: new FormControl(null, []), | password: new FormControl(null, []), | ||||
| isAdmin: new FormControl(null, [Validators.required]), | isAdmin: new FormControl(null, [Validators.required]), | ||||
| active: new FormControl(null, [Validators.required]), | active: new FormControl(null, [Validators.required]), | ||||
| isPilot: new FormControl(null, [Validators.required]), | |||||
| roles: new FormControl(null, []), | roles: new FormControl(null, []), | ||||
| createdAt: new FormControl(null, []) | createdAt: new FormControl(null, []) | ||||
| }); | }); | ||||
| @@ -190,6 +198,7 @@ export const userTripForm = new FormGroup({ | |||||
| userIri: new FormControl(null, [Validators.required]), | userIri: new FormControl(null, [Validators.required]), | ||||
| captainName: new FormControl(null, []), | captainName: new FormControl(null, []), | ||||
| completed: new FormControl(null, [Validators.required]), | completed: new FormControl(null, [Validators.required]), | ||||
| approved: new FormControl(null, [Validators.required]), | |||||
| signature: new FormControl(null, []), | signature: new FormControl(null, []), | ||||
| signatureIri: new FormControl(null, []), | signatureIri: new FormControl(null, []), | ||||
| signatureUrl: new FormControl(null, []), | signatureUrl: new FormControl(null, []), | ||||
| @@ -205,6 +214,7 @@ export const userTripJsonldForm = new FormGroup({ | |||||
| userIri: new FormControl(null, [Validators.required]), | userIri: new FormControl(null, [Validators.required]), | ||||
| captainName: new FormControl(null, []), | captainName: new FormControl(null, []), | ||||
| completed: new FormControl(null, [Validators.required]), | completed: new FormControl(null, [Validators.required]), | ||||
| approved: new FormControl(null, [Validators.required]), | |||||
| signature: new FormControl(null, []), | signature: new FormControl(null, []), | ||||
| signatureIri: new FormControl(null, []), | signatureIri: new FormControl(null, []), | ||||
| signatureUrl: new FormControl(null, []), | signatureUrl: new FormControl(null, []), | ||||
| @@ -246,6 +256,12 @@ export const vesselForm = new FormGroup({ | |||||
| code: new FormControl(null, [Validators.required]), | code: new FormControl(null, [Validators.required]), | ||||
| company: new FormControl(null, []), | company: new FormControl(null, []), | ||||
| companyIri: new FormControl(null, [Validators.required]), | companyIri: new FormControl(null, [Validators.required]), | ||||
| length: new FormControl(null, []), | |||||
| breadth: new FormControl(null, []), | |||||
| draft: new FormControl(null, []), | |||||
| grossTonnage: new FormControl(null, []), | |||||
| imoNo: new FormControl(null, []), | |||||
| callSign: new FormControl(null, []), | |||||
| createdAt: new FormControl(null, []) | createdAt: new FormControl(null, []) | ||||
| }); | }); | ||||
| @@ -255,6 +271,12 @@ export const vesselJsonldForm = new FormGroup({ | |||||
| code: new FormControl(null, [Validators.required]), | code: new FormControl(null, [Validators.required]), | ||||
| company: new FormControl(null, []), | company: new FormControl(null, []), | ||||
| companyIri: new FormControl(null, [Validators.required]), | companyIri: new FormControl(null, [Validators.required]), | ||||
| length: new FormControl(null, []), | |||||
| breadth: new FormControl(null, []), | |||||
| draft: new FormControl(null, []), | |||||
| grossTonnage: new FormControl(null, []), | |||||
| imoNo: new FormControl(null, []), | |||||
| callSign: new FormControl(null, []), | |||||
| createdAt: new FormControl(null, []) | createdAt: new FormControl(null, []) | ||||
| }); | }); | ||||
| @@ -48,6 +48,13 @@ | |||||
| <span class="slider round"></span> | <span class="slider round"></span> | ||||
| </label> | </label> | ||||
| </div> | </div> | ||||
| <div class="col-12 col-sm-6 col-md-4 col-lg-3 mb-3 switch-widget"> | |||||
| <p class="form-label">{{ 'location.is_start_end' | translate }}:</p> | |||||
| <label class="switch"> | |||||
| <input type="checkbox" formControlName="isStartEnd"> | |||||
| <span class="slider round"></span> | |||||
| </label> | |||||
| </div> | |||||
| </div> | </div> | ||||
| <div class="row"> | <div class="row"> | ||||
| <div class="col-12 mb-3"> | <div class="col-12 mb-3"> | ||||
| @@ -8,6 +8,7 @@ import {ListGetDataFunctionType} from "@app/_components/list/list-get-data-funct | |||||
| import {ROUTE_LOCATIONS} from "@app/app-routing.module"; | import {ROUTE_LOCATIONS} from "@app/app-routing.module"; | ||||
| import {Sort} from "@angular/material/sort"; | import {Sort} from "@angular/material/sort"; | ||||
| import {LocationFormComponent} from "@app/_views/location/location-form/location-form.component"; | import {LocationFormComponent} from "@app/_views/location/location-form/location-form.component"; | ||||
| import {SearchSelectComponent} from "@app/_components/search-select/search-select.component"; | |||||
| @Component({ | @Component({ | ||||
| selector: 'app-location-list', | selector: 'app-location-list', | ||||
| @@ -26,65 +27,7 @@ export class LocationListComponent implements OnInit, AfterViewInit { | |||||
| protected appHelperService: AppHelperService, | protected appHelperService: AppHelperService, | ||||
| ) { | ) { | ||||
| this.listColDefinitions = [ | |||||
| { | |||||
| name: 'name', | |||||
| text: 'common.name', | |||||
| type: ListComponent.COLUMN_TYPE_TEXT, | |||||
| field: 'name', | |||||
| sortable: true, | |||||
| filterType: FilterBarComponent.FILTER_TYPE_TEXT, | |||||
| } as ListColDefinition, | |||||
| { | |||||
| name: 'code', | |||||
| text: 'common.code', | |||||
| type: ListComponent.COLUMN_TYPE_TEXT, | |||||
| field: 'code', | |||||
| sortable: true, | |||||
| filterType: FilterBarComponent.FILTER_TYPE_TEXT, | |||||
| } as ListColDefinition, | |||||
| { | |||||
| name: 'zone', | |||||
| text: 'model.zone', | |||||
| type: ListComponent.COLUMN_TYPE_TEXT, | |||||
| subResource: 'zone', | |||||
| field: 'name', | |||||
| sortable: true, | |||||
| filterType: FilterBarComponent.FILTER_TYPE_TEXT, | |||||
| } as ListColDefinition, | |||||
| { | |||||
| name: 'is_zone', | |||||
| text: 'location.is_zone', | |||||
| type: ListComponent.COLUMN_TYPE_BOOLEAN, | |||||
| field: 'isZone', | |||||
| sortable: true, | |||||
| filterType: FilterBarComponent.FILTER_TYPE_BOOLEAN, | |||||
| } as ListColDefinition, | |||||
| { | |||||
| name: 'is_place', | |||||
| text: 'location.is_place', | |||||
| type: ListComponent.COLUMN_TYPE_BOOLEAN, | |||||
| field: 'isPlace', | |||||
| sortable: true, | |||||
| filterType: FilterBarComponent.FILTER_TYPE_BOOLEAN, | |||||
| } as ListColDefinition, | |||||
| { | |||||
| name: 'is_port', | |||||
| text: 'location.is_port', | |||||
| type: ListComponent.COLUMN_TYPE_BOOLEAN, | |||||
| field: 'isPort', | |||||
| sortable: true, | |||||
| filterType: FilterBarComponent.FILTER_TYPE_BOOLEAN, | |||||
| } as ListColDefinition, | |||||
| { | |||||
| name: 'createdAt', | |||||
| text: 'common.created_at', | |||||
| type: ListComponent.COLUMN_TYPE_DATE, | |||||
| field: 'createdAt', | |||||
| sortable: true, | |||||
| filterType: FilterBarComponent.FILTER_TYPE_DATE, | |||||
| } as ListColDefinition, | |||||
| ]; | |||||
| this.listColDefinitions = SearchSelectComponent.getDefaultColDefLocations(); | |||||
| } | } | ||||
| ngOnInit() { | ngOnInit() { | ||||
| @@ -70,6 +70,31 @@ | |||||
| {{ 'trip.is_arrival' | translate }} | {{ 'trip.is_arrival' | translate }} | ||||
| </label> | </label> | ||||
| </div> | </div> | ||||
| <div class="form-check"> | |||||
| <input | |||||
| class="form-check-input" | |||||
| type="checkbox" | |||||
| [id]="'isTransit_' + i" | |||||
| [checked]="tripLocation.isTransit" | |||||
| (change)="onIsTransitChange($event, i)" | |||||
| > | |||||
| <label class="form-check-label" [for]="'isTransit_' + i"> | |||||
| {{ 'trip.is_transit' | translate }} | |||||
| </label> | |||||
| </div> | |||||
| <div class="form-check"> | |||||
| <input | |||||
| class="form-check-input" | |||||
| type="checkbox" | |||||
| [id]="'isDeparture_' + i" | |||||
| [checked]="tripLocation.isDeparture" | |||||
| (change)="onIsDepartureChange($event, i)" | |||||
| > | |||||
| <label class="form-check-label" [for]="'isDeparture_' + i"> | |||||
| {{ 'trip.is_departure' | translate }} | |||||
| </label> | |||||
| </div> | |||||
| </div> | </div> | ||||
| <div class="col-12 col-md-2 mb-1 d-flex align-items-end"> | <div class="col-12 col-md-2 mb-1 d-flex align-items-end"> | ||||
| @@ -7,7 +7,7 @@ import { | |||||
| TripService, | TripService, | ||||
| LocationService, | LocationService, | ||||
| LocationJsonld, | LocationJsonld, | ||||
| UserTripService, UserService, UserTripJsonld, UserJsonld, UserTripEventJsonld, UserTripEventService | |||||
| UserTripService, UserService, UserTripJsonld, UserJsonld, UserTripEventJsonld, UserTripEventService, TripLocation | |||||
| } from "@app/core/api/v1"; | } from "@app/core/api/v1"; | ||||
| import { AppHelperService } from "@app/_helpers/app-helper.service"; | import { AppHelperService } from "@app/_helpers/app-helper.service"; | ||||
| import { ActivatedRoute } from "@angular/router"; | import { ActivatedRoute } from "@angular/router"; | ||||
| @@ -17,6 +17,7 @@ import {firstValueFrom, Observable} from 'rxjs'; | |||||
| import { ListColDefinition } from '@app/_components/list/list-col-definition'; | import { ListColDefinition } from '@app/_components/list/list-col-definition'; | ||||
| import { SearchSelectComponent } from '@app/_components/search-select/search-select.component'; | import { SearchSelectComponent } from '@app/_components/search-select/search-select.component'; | ||||
| import {map} from "rxjs/operators"; | import {map} from "rxjs/operators"; | ||||
| import {TranslateService} from "@ngx-translate/core"; | |||||
| @Component({ | @Component({ | ||||
| selector: 'app-trip-detail', | selector: 'app-trip-detail', | ||||
| @@ -35,6 +36,8 @@ export class TripDetailComponent implements OnInit, AfterViewInit { | |||||
| protected locationColDefinitions: ListColDefinition[] = SearchSelectComponent.getDefaultColDefLocations(); | protected locationColDefinitions: ListColDefinition[] = SearchSelectComponent.getDefaultColDefLocations(); | ||||
| protected userForms: FormGroup[] = []; | protected userForms: FormGroup[] = []; | ||||
| protected userColDefinitions: ListColDefinition[] = SearchSelectComponent.getDefaultColDefUsers(); | protected userColDefinitions: ListColDefinition[] = SearchSelectComponent.getDefaultColDefUsers(); | ||||
| protected originalTripLocations: TripLocation[] = []; | |||||
| @ViewChildren(SearchSelectComponent) searchSelects!: QueryList<SearchSelectComponent>; | @ViewChildren(SearchSelectComponent) searchSelects!: QueryList<SearchSelectComponent>; | ||||
| @@ -46,6 +49,7 @@ export class TripDetailComponent implements OnInit, AfterViewInit { | |||||
| private userTripEventService: UserTripEventService, | private userTripEventService: UserTripEventService, | ||||
| private userService: UserService, | private userService: UserService, | ||||
| protected appHelperService: AppHelperService, | protected appHelperService: AppHelperService, | ||||
| protected translateService: TranslateService, | |||||
| private route: ActivatedRoute, | private route: ActivatedRoute, | ||||
| private fb: FormBuilder | private fb: FormBuilder | ||||
| ) {} | ) {} | ||||
| @@ -85,16 +89,17 @@ export class TripDetailComponent implements OnInit, AfterViewInit { | |||||
| this.tripLocations = data.member; | this.tripLocations = data.member; | ||||
| // Create a form for each trip location | // Create a form for each trip location | ||||
| this.locationForms = []; | this.locationForms = []; | ||||
| this.tripLocations.forEach(() => { | |||||
| this.locationForms.push(this.createLocationForm()); | |||||
| this.originalTripLocations = JSON.parse(JSON.stringify(this.tripLocations)); | |||||
| this.tripLocations.forEach((tripLocation) => { | |||||
| this.locationForms.push(this.createLocationForm(tripLocation.location?.id ?? null)); | |||||
| }); | }); | ||||
| } | } | ||||
| ); | ); | ||||
| } | } | ||||
| createLocationForm(): FormGroup { | |||||
| createLocationForm(locationIri: string | null): FormGroup { | |||||
| return this.fb.group({ | return this.fb.group({ | ||||
| location: [null] | |||||
| location: [locationIri] | |||||
| }); | }); | ||||
| } | } | ||||
| @@ -126,7 +131,14 @@ export class TripDetailComponent implements OnInit, AfterViewInit { | |||||
| }); | }); | ||||
| // Filtere Benutzer, die bereits ausgewählt sind (gespeichert oder nicht) | // Filtere Benutzer, die bereits ausgewählt sind (gespeichert oder nicht) | ||||
| return this.userService.usersGetCollection(page, pageSize, undefined, term).pipe( | |||||
| return this.userService.usersGetCollection( | |||||
| page, | |||||
| pageSize, | |||||
| undefined, | |||||
| undefined, | |||||
| term, | |||||
| '{"isPilot":true}' | |||||
| ).pipe( | |||||
| map(response => { | map(response => { | ||||
| response.member = response.member.filter(user => | response.member = response.member.filter(user => | ||||
| !assignedUserIds.includes(this.appHelperService.extractId(user.id!)) | !assignedUserIds.includes(this.appHelperService.extractId(user.id!)) | ||||
| @@ -191,6 +203,16 @@ export class TripDetailComponent implements OnInit, AfterViewInit { | |||||
| this.tripLocations[index].isArrival = checkbox.checked; | this.tripLocations[index].isArrival = checkbox.checked; | ||||
| } | } | ||||
| onIsTransitChange(event: Event, index: number) { | |||||
| const checkbox = event.target as HTMLInputElement; | |||||
| this.tripLocations[index].isTransit = checkbox.checked; | |||||
| } | |||||
| onIsDepartureChange(event: Event, index: number) { | |||||
| const checkbox = event.target as HTMLInputElement; | |||||
| this.tripLocations[index].isDeparture = checkbox.checked; | |||||
| } | |||||
| addNewTripLocation() { | addNewTripLocation() { | ||||
| // Create a new empty trip location | // Create a new empty trip location | ||||
| const newTripLocation: TripLocationJsonld = { | const newTripLocation: TripLocationJsonld = { | ||||
| @@ -201,7 +223,7 @@ export class TripDetailComponent implements OnInit, AfterViewInit { | |||||
| }; | }; | ||||
| this.tripLocations.push(newTripLocation); | this.tripLocations.push(newTripLocation); | ||||
| this.locationForms.push(this.createLocationForm()); | |||||
| this.locationForms.push(this.createLocationForm(null)); | |||||
| // Force update in the next event loop to properly initialize the search-select | // Force update in the next event loop to properly initialize the search-select | ||||
| setTimeout(() => { | setTimeout(() => { | ||||
| @@ -219,7 +241,8 @@ export class TripDetailComponent implements OnInit, AfterViewInit { | |||||
| const newUserTrip: UserTripJsonld = { | const newUserTrip: UserTripJsonld = { | ||||
| tripIri: this.trip.id!, | tripIri: this.trip.id!, | ||||
| userIri: null, | userIri: null, | ||||
| completed: false | |||||
| completed: false, | |||||
| approved: false, | |||||
| }; | }; | ||||
| // Füge es als UserTripJsonld hinzu | // Füge es als UserTripJsonld hinzu | ||||
| @@ -280,79 +303,110 @@ export class TripDetailComponent implements OnInit, AfterViewInit { | |||||
| }) | }) | ||||
| } | } | ||||
| removeTripLocation(index: number) { | |||||
| const tripLocationId = this.tripLocations[index].id; | |||||
| if (tripLocationId) { | |||||
| // If it exists on the server, delete it | |||||
| this.tripLocationService.tripLocationsIdDelete(this.appHelperService.extractId(tripLocationId)).subscribe( | |||||
| () => { | |||||
| this.tripLocations.splice(index, 1); | |||||
| this.locationForms.splice(index, 1); | |||||
| } | |||||
| ); | |||||
| } else { | |||||
| // If it's only local, just remove it from the array | |||||
| removeTripLocation(index: number): void { | |||||
| this.translateService.get('basic.delete_confirm').subscribe((confirmMessage: string) => { | |||||
| if (!confirm(confirmMessage)) { | |||||
| return; | |||||
| } | |||||
| // Just remove from arrays; deletion happens later in saveAllTripLocations() | |||||
| this.tripLocations.splice(index, 1); | this.tripLocations.splice(index, 1); | ||||
| this.locationForms.splice(index, 1); | this.locationForms.splice(index, 1); | ||||
| } | |||||
| }); | |||||
| } | } | ||||
| removeUserTrip(index: number) { | removeUserTrip(index: number) { | ||||
| // Nur aus dem Array entfernen, tatsächliches Löschen erfolgt beim Speichern | |||||
| this.userTrips.splice(index, 1); | |||||
| this.userForms.splice(index, 1); | |||||
| this.translateService.get('basic.delete_confirm').subscribe((confirmMessage: string) => { | |||||
| if (!confirm(confirmMessage)) { | |||||
| return; | |||||
| } | |||||
| // Nur aus dem Array entfernen, tatsächliches Löschen erfolgt beim Speichern | |||||
| this.userTrips.splice(index, 1); | |||||
| this.userForms.splice(index, 1); | |||||
| }); | |||||
| } | } | ||||
| saveAllTripLocations() { | |||||
| saveAllTripLocations(): void { | |||||
| // A) DELETE: find which original dbIds are missing → delete those | |||||
| const originalDbIds = this.originalTripLocations | |||||
| .map(o => o.dbId) | |||||
| // narrow type to number (filter out null/undefined) | |||||
| .filter((id): id is number => id != null); | |||||
| const currentDbIds = this.tripLocations | |||||
| .map(t => t.dbId) | |||||
| .filter((id): id is number => id != null); | |||||
| const dbIdsToDelete = originalDbIds.filter(id => !currentDbIds.includes(id)); | |||||
| dbIdsToDelete.forEach(dbId => { | |||||
| this.tripLocationService | |||||
| .tripLocationsIdDelete(dbId.toString()) | |||||
| .subscribe({ | |||||
| next: () => console.log(`TripLocation ${dbId} deleted.`), | |||||
| error: err => console.error(`Error deleting TripLocation ${dbId}:`, err) | |||||
| }); | |||||
| }); | |||||
| // First update the location objects in our tripLocations array | |||||
| // B) UPSERT: create or update remaining entries | |||||
| this.tripLocations.forEach((tripLocation, index) => { | this.tripLocations.forEach((tripLocation, index) => { | ||||
| const locationFormValue = this.locationForms[index].get('location')?.value; | |||||
| const form = this.locationForms[index]; | |||||
| const locationVal = form.get('location')?.value; | |||||
| const dbId = tripLocation.dbId; | |||||
| const isNew = dbId == null; // no dbId → brand new | |||||
| // only for existing entries compare against snapshot | |||||
| let locationChanged = false; | |||||
| let modelChanged = false; | |||||
| if (!isNew) { | |||||
| const original = this.originalTripLocations[index]; | |||||
| locationChanged = locationVal !== original.locationIri; | |||||
| modelChanged = ( | |||||
| tripLocation.date !== original.date || | |||||
| tripLocation.isArrival !== original.isArrival || | |||||
| tripLocation.isTransit !== original.isTransit || | |||||
| tripLocation.isDeparture !== original.isDeparture | |||||
| ); | |||||
| } | |||||
| // Ensure we have a location | |||||
| if (locationFormValue) { | |||||
| // If just an ID was set, create a proper location object | |||||
| if (typeof locationFormValue === 'string') { | |||||
| tripLocation.locationIri = locationFormValue; | |||||
| } | |||||
| } else { | |||||
| // If no location is set, show an error | |||||
| // skip if neither new nor changed | |||||
| if (!(isNew || locationChanged || modelChanged)) { | |||||
| return; | return; | ||||
| } | } | ||||
| }); | |||||
| // Filter out trip locations that have no location set | |||||
| const validTripLocations = this.tripLocations.filter(tl => tl.locationIri); | |||||
| if (validTripLocations.length === 0) { | |||||
| return; | |||||
| } | |||||
| // Save all trip locations | |||||
| const savePromises = validTripLocations.map(tripLocation => { | |||||
| if (tripLocation.id) { | |||||
| // Update existing | |||||
| return firstValueFrom(this.tripLocationService.tripLocationsIdPatch( | |||||
| this.appHelperService.extractId(tripLocation.id), | |||||
| this.appHelperService.convertJsonldToJson(tripLocation) | |||||
| )); | |||||
| } else { | |||||
| // Create new | |||||
| return firstValueFrom(this.tripLocationService.tripLocationsPost(tripLocation)); | |||||
| // validate a location was chosen | |||||
| if (!locationVal) { | |||||
| console.error(`Location missing for entry #${index}`); | |||||
| return; | |||||
| } | } | ||||
| }); | |||||
| if (typeof locationVal === 'string') { | |||||
| tripLocation.locationIri = locationVal; | |||||
| } | |||||
| // always ensure the parent trip IRI is set | |||||
| tripLocation.tripIri = this.trip?.id ?? null; | |||||
| // choose correct API call | |||||
| const save$ = isNew | |||||
| ? this.tripLocationService.tripLocationsPost(tripLocation) | |||||
| : this.tripLocationService.tripLocationsIdPatch( | |||||
| dbId!.toString(), | |||||
| this.appHelperService.convertJsonldToJson(tripLocation) | |||||
| ); | |||||
| Promise.all(savePromises) | |||||
| .then(() => { | |||||
| // Reload trip locations to get updated data | |||||
| this.loadTripLocations(); | |||||
| }) | |||||
| .catch(error => { | |||||
| console.error('Error saving trip locations:', error); | |||||
| // execute save and log result | |||||
| save$.subscribe({ | |||||
| next: saved => { | |||||
| console.log(`TripLocation #${index} ${isNew ? 'created' : 'updated'}.`); | |||||
| }, | |||||
| error: err => { | |||||
| console.error(`Error saving TripLocation #${index}:`, err); | |||||
| } | |||||
| }); | }); | ||||
| }); | |||||
| // C) Finally: reset original snapshot to current state | |||||
| this.originalTripLocations = JSON.parse(JSON.stringify(this.tripLocations)); | |||||
| } | } | ||||
| saveAllUserTrips() { | saveAllUserTrips() { | ||||
| // Aktuelle IDs speichern, um später gelöschte Einträge zu identifizieren | // Aktuelle IDs speichern, um später gelöschte Einträge zu identifizieren | ||||
| let originalUserTripIds: string[] = []; | let originalUserTripIds: string[] = []; | ||||
| @@ -53,10 +53,6 @@ | |||||
| <label for="customerReference" class="form-label">{{ 'trip.customer_reference' | translate }}:</label> | <label for="customerReference" class="form-label">{{ 'trip.customer_reference' | translate }}:</label> | ||||
| <input type="text" class="form-control" id="customerReference" formControlName="customerReference"/> | <input type="text" class="form-control" id="customerReference" formControlName="customerReference"/> | ||||
| </div> | </div> | ||||
| <div class="col-12 col-lg-6 mb-3"> | |||||
| <label for="captainName" class="form-label">{{ 'trip.captain_name' | translate }}:</label> | |||||
| <input type="text" class="form-control" id="captainName" formControlName="captainName"/> | |||||
| </div> | |||||
| <div class="col-12 col-lg-6 mb-3"> | <div class="col-12 col-lg-6 mb-3"> | ||||
| <app-datetime-picker | <app-datetime-picker | ||||
| [label]="'trip.start_date' | translate" | [label]="'trip.start_date' | translate" | ||||
| @@ -60,6 +60,11 @@ export class TripFormComponent extends AbstractDataFormComponent<TripJsonld> { | |||||
| } | } | ||||
| getLocations: ListGetDataFunctionType = (index: number, pageSize: number, term?: string) => { | getLocations: ListGetDataFunctionType = (index: number, pageSize: number, term?: string) => { | ||||
| return this.locationService.locationsGetCollection(index, pageSize, term); | |||||
| return this.locationService.locationsGetCollection( | |||||
| index, | |||||
| pageSize, | |||||
| term, | |||||
| '{"isStartEnd":true}' | |||||
| ); | |||||
| } | } | ||||
| } | } | ||||
| @@ -49,14 +49,6 @@ export class TripListComponent { | |||||
| sortable: true, | sortable: true, | ||||
| filterType: FilterBarComponent.FILTER_TYPE_TEXT, | filterType: FilterBarComponent.FILTER_TYPE_TEXT, | ||||
| } as ListColDefinition, | } as ListColDefinition, | ||||
| { | |||||
| name: 'captainName', | |||||
| text: 'trip.captain_name', | |||||
| type: ListComponent.COLUMN_TYPE_TEXT, | |||||
| field: 'captainName', | |||||
| sortable: true, | |||||
| filterType: FilterBarComponent.FILTER_TYPE_TEXT, | |||||
| } as ListColDefinition, | |||||
| { | { | ||||
| name: 'startLocation', | name: 'startLocation', | ||||
| text: 'trip.start_location', | text: 'trip.start_location', | ||||
| @@ -2,15 +2,11 @@ import { Component, OnInit, AfterViewInit, QueryList, ViewChildren } from '@angu | |||||
| import { FormBuilder, FormGroup } from '@angular/forms'; | import { FormBuilder, FormGroup } from '@angular/forms'; | ||||
| import { | import { | ||||
| LocationService, | LocationService, | ||||
| TripJsonld, | |||||
| LocationJsonld, | |||||
| UserService, | |||||
| UserTripJsonld, | UserTripJsonld, | ||||
| UserTripService, | UserTripService, | ||||
| UserTripEventJsonld, | UserTripEventJsonld, | ||||
| UserTripEventService, | UserTripEventService, | ||||
| EventService, | EventService, | ||||
| EventJsonld | |||||
| } from "@app/core/api/v1"; | } from "@app/core/api/v1"; | ||||
| import { AppHelperService } from "@app/_helpers/app-helper.service"; | import { AppHelperService } from "@app/_helpers/app-helper.service"; | ||||
| import { ActivatedRoute } from "@angular/router"; | import { ActivatedRoute } from "@angular/router"; | ||||
| @@ -19,8 +15,6 @@ import { ModalStatus } from "@app/_helpers/modal.states"; | |||||
| import { firstValueFrom, Observable } from 'rxjs'; | import { firstValueFrom, Observable } from 'rxjs'; | ||||
| import { ListColDefinition } from '@app/_components/list/list-col-definition'; | import { ListColDefinition } from '@app/_components/list/list-col-definition'; | ||||
| import { SearchSelectComponent } from '@app/_components/search-select/search-select.component'; | import { SearchSelectComponent } from '@app/_components/search-select/search-select.component'; | ||||
| import { ListComponent } from '@app/_components/list/list.component'; | |||||
| import { FilterBarComponent } from "@app/_components/filter-bar/filter-bar.component"; | |||||
| @Component({ | @Component({ | ||||
| selector: 'app-user-trip-detail', | selector: 'app-user-trip-detail', | ||||
| @@ -17,6 +17,13 @@ | |||||
| <span class="slider round"></span> | <span class="slider round"></span> | ||||
| </label> | </label> | ||||
| </div> | </div> | ||||
| <div class="col-12 col-sm-6 col-md-4 col-lg-3 mb-3 switch-widget"> | |||||
| <p class="form-label">{{ 'user_trip.approved' | translate }}:</p> | |||||
| <label class="switch"> | |||||
| <input type="checkbox" formControlName="approved" [disabled]="data.approved"> | |||||
| <span class="slider round"></span> | |||||
| </label> | |||||
| </div> | |||||
| </div> | </div> | ||||
| @@ -29,9 +29,9 @@ export class UserTripFormComponent extends AbstractImageFormComponent<UserTripJs | |||||
| userTripForm, | userTripForm, | ||||
| undefined, | undefined, | ||||
| (id: string | number, data: UserTripJsonld) => | (id: string | number, data: UserTripJsonld) => | ||||
| userTripService.userTripsIdPatch( | |||||
| this.userTripService.userTripsIdPatch( | |||||
| id.toString(), | id.toString(), | ||||
| appHelperService.convertJsonldToJson(data) | |||||
| this.appHelperService.convertJsonldToJson(data) | |||||
| ), | ), | ||||
| (id: string | number) => userTripService.userTripsIdDelete(id.toString()), | (id: string | number) => userTripService.userTripsIdDelete(id.toString()), | ||||
| 'signatureIri', | 'signatureIri', | ||||
| @@ -82,6 +82,14 @@ export class UserTripListComponent { | |||||
| sortable: true, | sortable: true, | ||||
| filterType: FilterBarComponent.FILTER_TYPE_BOOLEAN, | filterType: FilterBarComponent.FILTER_TYPE_BOOLEAN, | ||||
| } as ListColDefinition, | } as ListColDefinition, | ||||
| { | |||||
| name: 'approved', | |||||
| text: 'user_trip.approved', | |||||
| type: ListComponent.COLUMN_TYPE_BOOLEAN, | |||||
| field: 'approved', | |||||
| sortable: true, | |||||
| filterType: FilterBarComponent.FILTER_TYPE_BOOLEAN, | |||||
| } as ListColDefinition, | |||||
| { | { | ||||
| name: 'completedDate', | name: 'completedDate', | ||||
| text: 'user_trip.completed_at', | text: 'user_trip.completed_at', | ||||
| @@ -42,6 +42,13 @@ | |||||
| <span class="slider round"></span> | <span class="slider round"></span> | ||||
| </label> | </label> | ||||
| </div> | </div> | ||||
| <div class="col-12 col-sm-6 col-md-4 col-lg-3 mb-3 switch-widget"> | |||||
| <p class="form-label">{{ 'users.is_pilot' | translate }}:</p> | |||||
| <label class="switch"> | |||||
| <input type="checkbox" formControlName="isPilot"> | |||||
| <span class="slider round"></span> | |||||
| </label> | |||||
| </div> | |||||
| </div> | </div> | ||||
| <app-image-upload | <app-image-upload | ||||
| @@ -65,6 +65,22 @@ export class UserListComponent implements OnInit, AfterViewInit { | |||||
| type: ListComponent.COLUMN_TYPE_TEXT_BOLD, | type: ListComponent.COLUMN_TYPE_TEXT_BOLD, | ||||
| field: 'referenceId', | field: 'referenceId', | ||||
| } as ListColDefinition, | } as ListColDefinition, | ||||
| { | |||||
| name: 'isAdmin', | |||||
| text: 'users.is_admin', | |||||
| type: ListComponent.COLUMN_TYPE_BOOLEAN, | |||||
| field: 'isAdmin', | |||||
| sortable: true, | |||||
| filterType: FilterBarComponent.FILTER_TYPE_BOOLEAN, | |||||
| } as ListColDefinition, | |||||
| { | |||||
| name: 'isPilot', | |||||
| text: 'users.is_pilot', | |||||
| type: ListComponent.COLUMN_TYPE_BOOLEAN, | |||||
| field: 'isPilot', | |||||
| sortable: true, | |||||
| filterType: FilterBarComponent.FILTER_TYPE_BOOLEAN, | |||||
| } as ListColDefinition, | |||||
| { | { | ||||
| name: 'active', | name: 'active', | ||||
| text: 'users.active', | text: 'users.active', | ||||
| @@ -91,6 +107,7 @@ export class UserListComponent implements OnInit, AfterViewInit { | |||||
| undefined, | undefined, | ||||
| undefined, | undefined, | ||||
| term, | term, | ||||
| this.listComponent.getFilterJsonString(), | |||||
| this.listComponent.getSortingJsonString() | this.listComponent.getSortingJsonString() | ||||
| ); | ); | ||||
| } | } | ||||
| @@ -35,6 +35,50 @@ | |||||
| <input id="companyIri" type="hidden" formControlName="companyIri"/> | <input id="companyIri" type="hidden" formControlName="companyIri"/> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="row"> | |||||
| <div class="col-12 col-lg-6 mb-3"> | |||||
| <label for="length" class="form-label">{{ 'vessel.length' | translate }}:</label> | |||||
| <input type="number" | |||||
| class="form-control" | |||||
| id="length" | |||||
| formControlName="length"/> | |||||
| </div> | |||||
| <div class="col-12 col-lg-6 mb-3"> | |||||
| <label for="breadth" class="form-label">{{ 'vessel.breadth' | translate }}:</label> | |||||
| <input type="number" | |||||
| class="form-control" | |||||
| id="breadth" | |||||
| formControlName="breadth"/> | |||||
| </div> | |||||
| <div class="col-12 col-lg-6 mb-3"> | |||||
| <label for="draft" class="form-label">{{ 'vessel.draft' | translate }}:</label> | |||||
| <input type="number" | |||||
| class="form-control" | |||||
| id="draft" | |||||
| formControlName="draft"/> | |||||
| </div> | |||||
| <div class="col-12 col-lg-6 mb-3"> | |||||
| <label for="grossTonnage" class="form-label">{{ 'vessel.grossTonnage' | translate }}:</label> | |||||
| <input type="number" | |||||
| class="form-control" | |||||
| id="grossTonnage" | |||||
| formControlName="grossTonnage"/> | |||||
| </div> | |||||
| <div class="col-12 col-lg-6 mb-3"> | |||||
| <label for="imoNo" class="form-label">{{ 'vessel.imoNo' | translate }}:</label> | |||||
| <input type="text" | |||||
| class="form-control" | |||||
| id="imoNo" | |||||
| formControlName="imoNo"/> | |||||
| </div> | |||||
| <div class="col-12 col-lg-6 mb-3"> | |||||
| <label for="callSign" class="form-label">{{ 'vessel.callSign' | translate }}:</label> | |||||
| <input type="text" | |||||
| class="form-control" | |||||
| id="callSign" | |||||
| formControlName="callSign"/> | |||||
| </div> | |||||
| </div> | |||||
| <div class="row"> | <div class="row"> | ||||
| <div class="col-12 mb-3"> | <div class="col-12 mb-3"> | ||||
| <button type="submit" class="btn btn-primary" [disabled]="form.invalid"> | <button type="submit" class="btn btn-primary" [disabled]="form.invalid"> | ||||
| @@ -1,12 +1,10 @@ | |||||
| import {Component, ViewChild} from '@angular/core'; | import {Component, ViewChild} from '@angular/core'; | ||||
| import {ListComponent} from "@app/_components/list/list.component"; | import {ListComponent} from "@app/_components/list/list.component"; | ||||
| import {ListColDefinition} from "@app/_components/list/list-col-definition"; | import {ListColDefinition} from "@app/_components/list/list-col-definition"; | ||||
| import {VesselJsonld, VesselService, ZoneJsonld} from "@app/core/api/v1"; | |||||
| import {VesselService, ZoneJsonld} from "@app/core/api/v1"; | |||||
| import {Router} from "@angular/router"; | import {Router} from "@angular/router"; | ||||
| import {AppHelperService} from "@app/_helpers/app-helper.service"; | 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 {ListGetDataFunctionType} from "@app/_components/list/list-get-data-function-type"; | ||||
| import {Sort} from "@angular/material/sort"; | |||||
| import {ROUTE_VESSELS, ROUTE_ZONES} from "@app/app-routing.module"; | import {ROUTE_VESSELS, ROUTE_ZONES} from "@app/app-routing.module"; | ||||
| import {VesselFormComponent} from "@app/_views/vessel/vessel-form/vessel-form.component"; | import {VesselFormComponent} from "@app/_views/vessel/vessel-form/vessel-form.component"; | ||||
| import {SearchSelectComponent} from "@app/_components/search-select/search-select.component"; | import {SearchSelectComponent} from "@app/_components/search-select/search-select.component"; | ||||
| @@ -109,14 +109,15 @@ export class UserService { | |||||
| * @param firstName | * @param firstName | ||||
| * @param lastName | * @param lastName | ||||
| * @param userNameSearch | * @param userNameSearch | ||||
| * @param customJsonFilter | |||||
| * @param customJsonOrder | * @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 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. | * @param reportProgress flag to report request and response progress. | ||||
| */ | */ | ||||
| public usersGetCollection(page?: number, itemsPerPage?: number, firstName?: string, lastName?: string, userNameSearch?: string, customJsonOrder?: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/ld+json' | 'application/problem+json' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<ApiUsersGetCollection200Response>; | |||||
| public usersGetCollection(page?: number, itemsPerPage?: number, firstName?: string, lastName?: string, userNameSearch?: string, customJsonOrder?: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/ld+json' | 'application/problem+json' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<HttpResponse<ApiUsersGetCollection200Response>>; | |||||
| public usersGetCollection(page?: number, itemsPerPage?: number, firstName?: string, lastName?: string, userNameSearch?: string, customJsonOrder?: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/ld+json' | 'application/problem+json' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<HttpEvent<ApiUsersGetCollection200Response>>; | |||||
| public usersGetCollection(page?: number, itemsPerPage?: number, firstName?: string, lastName?: string, userNameSearch?: 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> { | |||||
| public usersGetCollection(page?: number, itemsPerPage?: number, firstName?: string, lastName?: string, userNameSearch?: string, customJsonFilter?: string, customJsonOrder?: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/ld+json' | 'application/problem+json' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<ApiUsersGetCollection200Response>; | |||||
| public usersGetCollection(page?: number, itemsPerPage?: number, firstName?: string, lastName?: string, userNameSearch?: 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<ApiUsersGetCollection200Response>>; | |||||
| public usersGetCollection(page?: number, itemsPerPage?: number, firstName?: string, lastName?: string, userNameSearch?: 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<ApiUsersGetCollection200Response>>; | |||||
| public usersGetCollection(page?: number, itemsPerPage?: number, firstName?: string, lastName?: string, userNameSearch?: 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}); | let localVarQueryParameters = new HttpParams({encoder: this.encoder}); | ||||
| if (page !== undefined && page !== null) { | if (page !== undefined && page !== null) { | ||||
| @@ -139,6 +140,10 @@ export class UserService { | |||||
| localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, | localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, | ||||
| <any>userNameSearch, 'userNameSearch'); | <any>userNameSearch, 'userNameSearch'); | ||||
| } | } | ||||
| if (customJsonFilter !== undefined && customJsonFilter !== null) { | |||||
| localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, | |||||
| <any>customJsonFilter, 'custom_json_filter'); | |||||
| } | |||||
| if (customJsonOrder !== undefined && customJsonOrder !== null) { | if (customJsonOrder !== undefined && customJsonOrder !== null) { | ||||
| localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, | localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, | ||||
| <any>customJsonOrder, 'custom_json_order'); | <any>customJsonOrder, 'custom_json_order'); | ||||
| @@ -24,6 +24,7 @@ export interface Location { | |||||
| isZone?: boolean; | isZone?: boolean; | ||||
| isPlace?: boolean; | isPlace?: boolean; | ||||
| isPort?: boolean; | isPort?: boolean; | ||||
| isStartEnd?: boolean; | |||||
| readonly createdAt?: string | null; | readonly createdAt?: string | null; | ||||
| } | } | ||||
| @@ -28,6 +28,7 @@ export interface LocationJsonld { | |||||
| isZone?: boolean; | isZone?: boolean; | ||||
| isPlace?: boolean; | isPlace?: boolean; | ||||
| isPort?: boolean; | isPort?: boolean; | ||||
| isStartEnd?: boolean; | |||||
| readonly createdAt?: string | null; | readonly createdAt?: string | null; | ||||
| } | } | ||||
| @@ -20,7 +20,6 @@ export interface Trip { | |||||
| vesselIri: string | null; | vesselIri: string | null; | ||||
| readonly pilotageReference?: string | null; | readonly pilotageReference?: string | null; | ||||
| customerReference?: string | null; | customerReference?: string | null; | ||||
| captainName?: string | null; | |||||
| readonly startLocation?: string; | readonly startLocation?: string; | ||||
| startLocationIri: string | null; | startLocationIri: string | null; | ||||
| readonly endLocation?: string; | readonly endLocation?: string; | ||||
| @@ -28,6 +27,7 @@ export interface Trip { | |||||
| startDate: string; | startDate: string; | ||||
| endDate: string; | endDate: string; | ||||
| note?: string | null; | note?: string | null; | ||||
| completed?: boolean; | |||||
| readonly createdAt?: string | null; | readonly createdAt?: string | null; | ||||
| } | } | ||||
| @@ -25,7 +25,6 @@ export interface TripJsonld { | |||||
| vesselIri: string | null; | vesselIri: string | null; | ||||
| readonly pilotageReference?: string | null; | readonly pilotageReference?: string | null; | ||||
| customerReference?: string | null; | customerReference?: string | null; | ||||
| captainName?: string | null; | |||||
| readonly startLocation?: LocationJsonld; | readonly startLocation?: LocationJsonld; | ||||
| startLocationIri: string | null; | startLocationIri: string | null; | ||||
| readonly endLocation?: LocationJsonld; | readonly endLocation?: LocationJsonld; | ||||
| @@ -33,6 +32,7 @@ export interface TripJsonld { | |||||
| startDate: string; | startDate: string; | ||||
| endDate: string; | endDate: string; | ||||
| note?: string | null; | note?: string | null; | ||||
| completed?: boolean; | |||||
| readonly createdAt?: string | null; | readonly createdAt?: string | null; | ||||
| } | } | ||||
| @@ -23,6 +23,8 @@ export interface TripLocation { | |||||
| location?: Location; | location?: Location; | ||||
| locationIri: string | null; | locationIri: string | null; | ||||
| isArrival?: boolean; | isArrival?: boolean; | ||||
| isTransit?: boolean; | |||||
| isDeparture?: boolean; | |||||
| date: string; | date: string; | ||||
| readonly createdAt?: string | null; | readonly createdAt?: string | null; | ||||
| } | } | ||||
| @@ -26,6 +26,8 @@ export interface TripLocationJsonld { | |||||
| location?: LocationJsonld; | location?: LocationJsonld; | ||||
| locationIri: string | null; | locationIri: string | null; | ||||
| isArrival?: boolean; | isArrival?: boolean; | ||||
| isTransit?: boolean; | |||||
| isDeparture?: boolean; | |||||
| date: string; | date: string; | ||||
| readonly createdAt?: string | null; | readonly createdAt?: string | null; | ||||
| } | } | ||||
| @@ -30,6 +30,7 @@ export interface User { | |||||
| password?: string | null; | password?: string | null; | ||||
| isAdmin: boolean; | isAdmin: boolean; | ||||
| active: boolean; | active: boolean; | ||||
| isPilot: boolean; | |||||
| roles?: Array<string>; | roles?: Array<string>; | ||||
| readonly createdAt?: string | null; | readonly createdAt?: string | null; | ||||
| } | } | ||||
| @@ -34,6 +34,7 @@ export interface UserJsonld { | |||||
| password?: string | null; | password?: string | null; | ||||
| isAdmin: boolean; | isAdmin: boolean; | ||||
| active: boolean; | active: boolean; | ||||
| isPilot: boolean; | |||||
| roles?: Array<string>; | roles?: Array<string>; | ||||
| readonly createdAt?: string | null; | readonly createdAt?: string | null; | ||||
| } | } | ||||
| @@ -22,6 +22,7 @@ export interface UserTrip { | |||||
| userIri: string | null; | userIri: string | null; | ||||
| captainName?: string | null; | captainName?: string | null; | ||||
| completed: boolean; | completed: boolean; | ||||
| approved: boolean; | |||||
| readonly signature?: string; | readonly signature?: string; | ||||
| signatureIri?: string | null; | signatureIri?: string | null; | ||||
| readonly signatureUrl?: string | null; | readonly signatureUrl?: string | null; | ||||
| @@ -28,6 +28,7 @@ export interface UserTripJsonld { | |||||
| userIri: string | null; | userIri: string | null; | ||||
| captainName?: string | null; | captainName?: string | null; | ||||
| completed: boolean; | completed: boolean; | ||||
| approved: boolean; | |||||
| readonly signature?: MediaObjectJsonld; | readonly signature?: MediaObjectJsonld; | ||||
| signatureIri?: string | null; | signatureIri?: string | null; | ||||
| readonly signatureUrl?: string | null; | readonly signatureUrl?: string | null; | ||||
| @@ -20,6 +20,12 @@ export interface Vessel { | |||||
| code: string; | code: string; | ||||
| readonly company?: string; | readonly company?: string; | ||||
| companyIri: string | null; | companyIri: string | null; | ||||
| length?: number | null; | |||||
| breadth?: number | null; | |||||
| draft?: number | null; | |||||
| grossTonnage?: number | null; | |||||
| imoNo?: string | null; | |||||
| callSign?: string | null; | |||||
| readonly createdAt?: string | null; | readonly createdAt?: string | null; | ||||
| } | } | ||||
| @@ -24,6 +24,12 @@ export interface VesselJsonld { | |||||
| code: string; | code: string; | ||||
| readonly company?: ShippingCompanyJsonld; | readonly company?: ShippingCompanyJsonld; | ||||
| companyIri: string | null; | companyIri: string | null; | ||||
| length?: number | null; | |||||
| breadth?: number | null; | |||||
| draft?: number | null; | |||||
| grossTonnage?: number | null; | |||||
| imoNo?: string | null; | |||||
| callSign?: string | null; | |||||
| readonly createdAt?: string | null; | readonly createdAt?: string | null; | ||||
| } | } | ||||
| @@ -30,24 +30,27 @@ | |||||
| "end_location": "End location", | "end_location": "End location", | ||||
| "start_date": "Start date", | "start_date": "Start date", | ||||
| "end_date": "End date", | "end_date": "End date", | ||||
| "is_arrival": "is arrival", | |||||
| "is_arrival": "Arrival", | |||||
| "is_transit": "Transit", | |||||
| "is_departure": "Departure", | |||||
| "itinerary": "Itinerary", | "itinerary": "Itinerary", | ||||
| "itinerary_locations": "Itinerary locations", | "itinerary_locations": "Itinerary locations", | ||||
| "add_itinerary_location": "Add itinerary location", | "add_itinerary_location": "Add itinerary location", | ||||
| "remove_itinerary_location": "Remove itinerary location", | "remove_itinerary_location": "Remove itinerary location", | ||||
| "save_itinerary": "Save itinerary", | "save_itinerary": "Save itinerary", | ||||
| "assigned_users": "Assigned Users (User Trips)", | |||||
| "assigned_users": "Assigned Pilots", | |||||
| "save_user_assignments": "Save user assignments", | "save_user_assignments": "Save user assignments", | ||||
| "events": "Events" | "events": "Events" | ||||
| }, | }, | ||||
| "user_trip": | "user_trip": | ||||
| { | { | ||||
| "view": "User Trips", | |||||
| "view": "Pilotage", | |||||
| "events": "Events", | "events": "Events", | ||||
| "completed": "Completed", | "completed": "Completed", | ||||
| "completed_at": "Completed at", | "completed_at": "Completed at", | ||||
| "signature": "Signature Image", | "signature": "Signature Image", | ||||
| "event_date": "Event date" | |||||
| "event_date": "Event date", | |||||
| "approved": "Approved" | |||||
| }, | }, | ||||
| "base_data": | "base_data": | ||||
| { | { | ||||
| @@ -64,18 +67,28 @@ | |||||
| "shipping_company": "Shipping Company", | "shipping_company": "Shipping Company", | ||||
| "trip": "Trip", | "trip": "Trip", | ||||
| "user": "User", | "user": "User", | ||||
| "user_trip": "User Trip", | |||||
| "user_trip": "Pilotage", | |||||
| "event": "Event" | "event": "Event" | ||||
| }, | }, | ||||
| "location": | "location": | ||||
| { | { | ||||
| "is_zone": "Is zone", | |||||
| "is_place": "Is place", | |||||
| "is_port": "Is port" | |||||
| "is_zone": "Zone", | |||||
| "is_place": "Place", | |||||
| "is_port": "Port", | |||||
| "is_start_end": "Start/End" | |||||
| }, | }, | ||||
| "zone": | "zone": | ||||
| { | { | ||||
| }, | |||||
| "vessel": | |||||
| { | |||||
| "length": "Length", | |||||
| "breadth": "Breadth", | |||||
| "draft": "Draft", | |||||
| "grossTonnage": "Gross Tonnage", | |||||
| "imoNo": "Imo", | |||||
| "callSign": "Call sign" | |||||
| }, | }, | ||||
| "profile": | "profile": | ||||
| { | { | ||||
| @@ -85,7 +98,7 @@ | |||||
| { | { | ||||
| "logout": "Logout", | "logout": "Logout", | ||||
| "company_name": "Imaq Pilotage", | "company_name": "Imaq Pilotage", | ||||
| "users": "Users", | |||||
| "users": "Users / Pilots", | |||||
| "new": "New", | "new": "New", | ||||
| "edit_before": "", | "edit_before": "", | ||||
| "edit_after": "Edit", | "edit_after": "Edit", | ||||
| @@ -113,26 +126,28 @@ | |||||
| "edit": "Edit", | "edit": "Edit", | ||||
| "save": "Save", | "save": "Save", | ||||
| "delete": "Delete", | "delete": "Delete", | ||||
| "delete_confirm": "Do you really want to delete this dataset? There might be related data, which makes deletion impossible unless the related data will be removed first!" | |||||
| "delete_confirm": "Do you really want to delete this dataset?", | |||||
| "delete_confirm_related": "Do you really want to delete this dataset? There might be related data, which makes deletion impossible unless the related data will be removed first!" | |||||
| }, | }, | ||||
| "users": | "users": | ||||
| { | { | ||||
| "view": "Users", | |||||
| "view": "Users / Pilots", | |||||
| "user": "User", | "user": "User", | ||||
| "email": "Email", | "email": "Email", | ||||
| "full_name": "Name", | "full_name": "Name", | ||||
| "firstname": "Firstname", | "firstname": "Firstname", | ||||
| "lastname": "Lastname", | "lastname": "Lastname", | ||||
| "userTrips": "User trips", | |||||
| "userTrips": "Pilotage", | |||||
| "pilotIdNo": "#Pilot id", | "pilotIdNo": "#Pilot id", | ||||
| "password": "Password", | "password": "Password", | ||||
| "active": "Active", | "active": "Active", | ||||
| "image": "Image", | "image": "Image", | ||||
| "is_admin": "Is admin" | |||||
| "is_admin": "Admin", | |||||
| "is_pilot": "Pilot" | |||||
| }, | }, | ||||
| "form": | "form": | ||||
| { | { | ||||
| "mandatory": " is mandatory", | |||||
| "mandatory": " Mandatory", | |||||
| "email_validation": "Please provide a valid email address", | "email_validation": "Please provide a valid email address", | ||||
| "search_placeholder": "Search", | "search_placeholder": "Search", | ||||
| "no_data": "No datasets found." | "no_data": "No datasets found." | ||||
| @@ -0,0 +1,65 @@ | |||||
| <?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 Version20250428094124 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(<<<'SQL' | |||||
| ALTER TABLE location ADD is_start_end TINYINT(1) NOT NULL | |||||
| SQL); | |||||
| $this->addSql(<<<'SQL' | |||||
| ALTER TABLE trip ADD completed TINYINT(1) NOT NULL, DROP captain_name | |||||
| SQL); | |||||
| $this->addSql(<<<'SQL' | |||||
| ALTER TABLE trip_location ADD is_transit TINYINT(1) NOT NULL, ADD is_departure TINYINT(1) NOT NULL | |||||
| SQL); | |||||
| $this->addSql(<<<'SQL' | |||||
| ALTER TABLE user ADD is_pilot TINYINT(1) NOT NULL | |||||
| SQL); | |||||
| $this->addSql(<<<'SQL' | |||||
| ALTER TABLE user_trip ADD approved TINYINT(1) NOT NULL | |||||
| SQL); | |||||
| $this->addSql(<<<'SQL' | |||||
| ALTER TABLE vessel ADD length DOUBLE PRECISION DEFAULT NULL, ADD breadth DOUBLE PRECISION DEFAULT NULL, ADD draft DOUBLE PRECISION DEFAULT NULL, ADD gross_tonnage DOUBLE PRECISION DEFAULT NULL, ADD imo_no VARCHAR(255) DEFAULT NULL, ADD call_sign VARCHAR(255) DEFAULT NULL | |||||
| SQL); | |||||
| } | |||||
| public function down(Schema $schema): void | |||||
| { | |||||
| // this down() migration is auto-generated, please modify it to your needs | |||||
| $this->addSql(<<<'SQL' | |||||
| ALTER TABLE location DROP is_start_end | |||||
| SQL); | |||||
| $this->addSql(<<<'SQL' | |||||
| ALTER TABLE `user` DROP is_pilot | |||||
| SQL); | |||||
| $this->addSql(<<<'SQL' | |||||
| ALTER TABLE vessel DROP length, DROP breadth, DROP draft, DROP gross_tonnage, DROP imo_no, DROP call_sign | |||||
| SQL); | |||||
| $this->addSql(<<<'SQL' | |||||
| ALTER TABLE trip_location DROP is_transit, DROP is_departure | |||||
| SQL); | |||||
| $this->addSql(<<<'SQL' | |||||
| ALTER TABLE trip ADD captain_name VARCHAR(255) DEFAULT NULL, DROP completed | |||||
| SQL); | |||||
| $this->addSql(<<<'SQL' | |||||
| ALTER TABLE user_trip DROP approved | |||||
| SQL); | |||||
| } | |||||
| } | |||||
| @@ -93,6 +93,8 @@ class LocationApi | |||||
| public bool $isPort; | public bool $isPort; | ||||
| public bool $isStartEnd; | |||||
| #[ApiProperty(writable: false)] | #[ApiProperty(writable: false)] | ||||
| public ?\DateTimeImmutable $createdAt = null; | public ?\DateTimeImmutable $createdAt = null; | ||||
| } | } | ||||
| @@ -83,8 +83,6 @@ class TripApi | |||||
| public ?string $customerReference = null; | public ?string $customerReference = null; | ||||
| public ?string $captainName = null; | |||||
| /** | /** | ||||
| * @var LocationApi | * @var LocationApi | ||||
| */ | */ | ||||
| @@ -133,6 +131,8 @@ class TripApi | |||||
| public ?string $note; | public ?string $note; | ||||
| public bool $completed = false; | |||||
| #[ApiProperty(writable: false)] | #[ApiProperty(writable: false)] | ||||
| public ?\DateTimeImmutable $createdAt = null; | public ?\DateTimeImmutable $createdAt = null; | ||||
| } | } | ||||
| @@ -98,7 +98,11 @@ class TripLocationApi | |||||
| #[ApiProperty(writable: true)] | #[ApiProperty(writable: true)] | ||||
| public ?LocationApi $locationIri = null; | public ?LocationApi $locationIri = null; | ||||
| public bool $isArrival; | |||||
| public bool $isArrival = false; | |||||
| public bool $isTransit = false; | |||||
| public bool $isDeparture = false; | |||||
| #[Assert\NotBlank] | #[Assert\NotBlank] | ||||
| public \DateTimeImmutable $date; | public \DateTimeImmutable $date; | ||||
| @@ -18,6 +18,7 @@ use ApiPlatform\Metadata\GetCollection; | |||||
| use ApiPlatform\Metadata\Patch; | use ApiPlatform\Metadata\Patch; | ||||
| use ApiPlatform\Metadata\Post; | use ApiPlatform\Metadata\Post; | ||||
| use App\Entity\User; | use App\Entity\User; | ||||
| use App\Filter\CustomJsonFilter; | |||||
| use App\Filter\CustomJsonOrderFilter; | use App\Filter\CustomJsonOrderFilter; | ||||
| use App\Filter\UserNameSearchFilter; | use App\Filter\UserNameSearchFilter; | ||||
| use App\State\EntityClassDtoStateProcessor; | use App\State\EntityClassDtoStateProcessor; | ||||
| @@ -53,6 +54,7 @@ use Symfony\Component\Validator\Constraints as Assert; | |||||
| )] | )] | ||||
| #[ApiFilter(SearchFilter::class, properties: ['firstName' => 'ipartial', 'lastName' => 'ipartial'])] | #[ApiFilter(SearchFilter::class, properties: ['firstName' => 'ipartial', 'lastName' => 'ipartial'])] | ||||
| #[ApiFilter(UserNameSearchFilter::class)] | #[ApiFilter(UserNameSearchFilter::class)] | ||||
| #[ApiFilter(CustomJsonFilter::class)] | |||||
| #[ApiFilter(CustomJsonOrderFilter::class)] | #[ApiFilter(CustomJsonOrderFilter::class)] | ||||
| class UserApi | class UserApi | ||||
| { | { | ||||
| @@ -113,6 +115,9 @@ class UserApi | |||||
| #[Assert\NotNull] | #[Assert\NotNull] | ||||
| public bool $active = false; | public bool $active = false; | ||||
| #[Assert\NotNull] | |||||
| public bool $isPilot = false; | |||||
| #[ApiProperty(writable: false)] | #[ApiProperty(writable: false)] | ||||
| public array $roles = []; | public array $roles = []; | ||||
| @@ -105,6 +105,9 @@ class UserTripApi | |||||
| #[Assert\NotNull] | #[Assert\NotNull] | ||||
| public bool $completed = false; | public bool $completed = false; | ||||
| #[Assert\NotNull] | |||||
| public bool $approved = false; | |||||
| /** | /** | ||||
| * @var MediaObjectApi | * @var MediaObjectApi | ||||
| */ | */ | ||||
| @@ -84,6 +84,18 @@ class VesselApi | |||||
| #[ApiProperty(writable: true)] | #[ApiProperty(writable: true)] | ||||
| public ?ShippingCompanyApi $companyIri = null; | public ?ShippingCompanyApi $companyIri = null; | ||||
| public ?float $length = null; | |||||
| public ?float $breadth = null; | |||||
| public ?float $draft = null; | |||||
| public ?float $grossTonnage = null; | |||||
| public ?string $imoNo = null; | |||||
| public ?string $callSign = null; | |||||
| #[ApiProperty(writable: false)] | #[ApiProperty(writable: false)] | ||||
| public ?\DateTimeImmutable $createdAt = null; | public ?\DateTimeImmutable $createdAt = null; | ||||
| } | } | ||||
| @@ -37,6 +37,9 @@ class Location | |||||
| #[ORM\Column(nullable: false)] | #[ORM\Column(nullable: false)] | ||||
| private bool $isPort = false; | private bool $isPort = false; | ||||
| #[ORM\Column(nullable: false)] | |||||
| private bool $isStartEnd = false; | |||||
| #[ORM\Column] | #[ORM\Column] | ||||
| private DateTimeImmutable $createdAt; | private DateTimeImmutable $createdAt; | ||||
| @@ -119,6 +122,16 @@ class Location | |||||
| $this->isPort = $isPort; | $this->isPort = $isPort; | ||||
| } | } | ||||
| public function isStartEnd(): bool | |||||
| { | |||||
| return $this->isStartEnd; | |||||
| } | |||||
| public function setIsStartEnd(bool $isStartEnd): void | |||||
| { | |||||
| $this->isStartEnd = $isStartEnd; | |||||
| } | |||||
| public function getCreatedAt(): DateTimeImmutable | public function getCreatedAt(): DateTimeImmutable | ||||
| { | { | ||||
| return $this->createdAt; | return $this->createdAt; | ||||
| @@ -25,9 +25,6 @@ class Trip | |||||
| #[ORM\Column(length: 255, nullable: true)] | #[ORM\Column(length: 255, nullable: true)] | ||||
| private ?string $customerReference = null; | private ?string $customerReference = null; | ||||
| #[ORM\Column(length: 255, nullable: true)] | |||||
| private ?string $captainName = null; | |||||
| #[ORM\ManyToOne(targetEntity: Location::class)] | #[ORM\ManyToOne(targetEntity: Location::class)] | ||||
| #[ORM\JoinColumn(name: 'start_location_id', nullable: false)] | #[ORM\JoinColumn(name: 'start_location_id', nullable: false)] | ||||
| private Location $startLocation; | private Location $startLocation; | ||||
| @@ -45,6 +42,9 @@ class Trip | |||||
| #[ORM\Column(type: "text", nullable: true)] | #[ORM\Column(type: "text", nullable: true)] | ||||
| protected ?string $note; | protected ?string $note; | ||||
| #[ORM\Column(nullable: false)] | |||||
| private bool $completed = false; | |||||
| #[ORM\Column] | #[ORM\Column] | ||||
| private DateTimeImmutable $createdAt; | private DateTimeImmutable $createdAt; | ||||
| @@ -97,17 +97,6 @@ class Trip | |||||
| $this->customerReference = $customerReference; | $this->customerReference = $customerReference; | ||||
| } | } | ||||
| public function getCaptainName(): ?string | |||||
| { | |||||
| return $this->captainName; | |||||
| } | |||||
| public function setCaptainName(?string $captainName): self | |||||
| { | |||||
| $this->captainName = $captainName; | |||||
| return $this; | |||||
| } | |||||
| public function getStartLocation(): Location | public function getStartLocation(): Location | ||||
| { | { | ||||
| return $this->startLocation; | return $this->startLocation; | ||||
| @@ -162,6 +151,16 @@ class Trip | |||||
| $this->note = $note; | $this->note = $note; | ||||
| } | } | ||||
| public function isCompleted(): bool | |||||
| { | |||||
| return $this->completed; | |||||
| } | |||||
| public function setCompleted(bool $completed): void | |||||
| { | |||||
| $this->completed = $completed; | |||||
| } | |||||
| public function getCreatedAt(): DateTimeImmutable | public function getCreatedAt(): DateTimeImmutable | ||||
| { | { | ||||
| return $this->createdAt; | return $this->createdAt; | ||||
| @@ -27,6 +27,12 @@ class TripLocation | |||||
| #[ORM\Column(nullable: false)] | #[ORM\Column(nullable: false)] | ||||
| private bool $isArrival = true; | private bool $isArrival = true; | ||||
| #[ORM\Column(nullable: false)] | |||||
| private bool $isTransit = true; | |||||
| #[ORM\Column(nullable: false)] | |||||
| private bool $isDeparture = true; | |||||
| #[ORM\Column] | #[ORM\Column] | ||||
| private DateTimeImmutable $date; | private DateTimeImmutable $date; | ||||
| @@ -89,6 +95,26 @@ class TripLocation | |||||
| $this->isArrival = $isArrival; | $this->isArrival = $isArrival; | ||||
| } | } | ||||
| public function isTransit(): bool | |||||
| { | |||||
| return $this->isTransit; | |||||
| } | |||||
| public function setIsTransit(bool $isTransit): void | |||||
| { | |||||
| $this->isTransit = $isTransit; | |||||
| } | |||||
| public function isDeparture(): bool | |||||
| { | |||||
| return $this->isDeparture; | |||||
| } | |||||
| public function setIsDeparture(bool $isDeparture): void | |||||
| { | |||||
| $this->isDeparture = $isDeparture; | |||||
| } | |||||
| public function getCreatedAt(): DateTimeImmutable | public function getCreatedAt(): DateTimeImmutable | ||||
| { | { | ||||
| return $this->createdAt; | return $this->createdAt; | ||||
| @@ -35,6 +35,9 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface | |||||
| #[ORM\JoinColumn(nullable: true, onDelete: "SET NULL")] | #[ORM\JoinColumn(nullable: true, onDelete: "SET NULL")] | ||||
| private ?MediaObject $image = null; | private ?MediaObject $image = null; | ||||
| #[ORM\Column(nullable: false)] | |||||
| private bool $isPilot = false; | |||||
| #[ORM\Column] | #[ORM\Column] | ||||
| private array $roles = []; | private array $roles = []; | ||||
| @@ -180,6 +183,16 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface | |||||
| $this->active = $active; | $this->active = $active; | ||||
| } | } | ||||
| public function isPilot(): bool | |||||
| { | |||||
| return $this->isPilot; | |||||
| } | |||||
| public function setIsPilot(bool $isPilot): void | |||||
| { | |||||
| $this->isPilot = $isPilot; | |||||
| } | |||||
| public function getCreatedAt(): ?\DateTimeImmutable | public function getCreatedAt(): ?\DateTimeImmutable | ||||
| { | { | ||||
| return $this->createdAt; | return $this->createdAt; | ||||
| @@ -37,6 +37,9 @@ class UserTrip | |||||
| #[ORM\Column(nullable: false)] | #[ORM\Column(nullable: false)] | ||||
| private bool $completed = false; | private bool $completed = false; | ||||
| #[ORM\Column(nullable: false)] | |||||
| private bool $approved = false; | |||||
| #[ORM\Column(nullable: true)] | #[ORM\Column(nullable: true)] | ||||
| private ?DateTimeImmutable $completedDate; | private ?DateTimeImmutable $completedDate; | ||||
| @@ -124,6 +127,16 @@ class UserTrip | |||||
| $this->completed = $completed; | $this->completed = $completed; | ||||
| } | } | ||||
| public function isApproved(): bool | |||||
| { | |||||
| return $this->approved; | |||||
| } | |||||
| public function setApproved(bool $approved): void | |||||
| { | |||||
| $this->approved = $approved; | |||||
| } | |||||
| public function getUserTripEvents(): Collection | public function getUserTripEvents(): Collection | ||||
| { | { | ||||
| return $this->userTripEvents; | return $this->userTripEvents; | ||||
| @@ -28,6 +28,24 @@ class Vessel | |||||
| #[ORM\Column(length: 255, unique: true)] | #[ORM\Column(length: 255, unique: true)] | ||||
| private string $code; | private string $code; | ||||
| #[ORM\Column(nullable: true)] | |||||
| private ?float $length = null; | |||||
| #[ORM\Column(nullable: true)] | |||||
| private ?float $breadth = null; | |||||
| #[ORM\Column(nullable: true)] | |||||
| private ?float $draft = null; | |||||
| #[ORM\Column(nullable: true)] | |||||
| private ?float $grossTonnage = null; | |||||
| #[ORM\Column(length: 255, nullable: true)] | |||||
| private ?string $imoNo = null; | |||||
| #[ORM\Column(length: 255, nullable: true)] | |||||
| private ?string $callSign = null; | |||||
| #[ORM\Column] | #[ORM\Column] | ||||
| private DateTimeImmutable $createdAt; | private DateTimeImmutable $createdAt; | ||||
| @@ -80,6 +98,66 @@ class Vessel | |||||
| $this->code = $code; | $this->code = $code; | ||||
| } | } | ||||
| public function getLength(): ?float | |||||
| { | |||||
| return $this->length; | |||||
| } | |||||
| public function setLength(?float $length): void | |||||
| { | |||||
| $this->length = $length; | |||||
| } | |||||
| public function getBreadth(): ?float | |||||
| { | |||||
| return $this->breadth; | |||||
| } | |||||
| public function setBreadth(?float $breadth): void | |||||
| { | |||||
| $this->breadth = $breadth; | |||||
| } | |||||
| public function getDraft(): ?float | |||||
| { | |||||
| return $this->draft; | |||||
| } | |||||
| public function setDraft(?float $draft): void | |||||
| { | |||||
| $this->draft = $draft; | |||||
| } | |||||
| public function getGrossTonnage(): ?float | |||||
| { | |||||
| return $this->grossTonnage; | |||||
| } | |||||
| public function setGrossTonnage(?float $grossTonnage): void | |||||
| { | |||||
| $this->grossTonnage = $grossTonnage; | |||||
| } | |||||
| public function getImoNo(): ?string | |||||
| { | |||||
| return $this->imoNo; | |||||
| } | |||||
| public function setImoNo(?string $imoNo): void | |||||
| { | |||||
| $this->imoNo = $imoNo; | |||||
| } | |||||
| public function getCallSign(): ?string | |||||
| { | |||||
| return $this->callSign; | |||||
| } | |||||
| public function setCallSign(?string $callSign): void | |||||
| { | |||||
| $this->callSign = $callSign; | |||||
| } | |||||
| public function getCreatedAt(): DateTimeImmutable | public function getCreatedAt(): DateTimeImmutable | ||||
| { | { | ||||
| return $this->createdAt; | return $this->createdAt; | ||||
| @@ -6,6 +6,7 @@ use ApiPlatform\Doctrine\Orm\Filter\AbstractFilter; | |||||
| use ApiPlatform\Doctrine\Orm\Util\QueryNameGeneratorInterface; | use ApiPlatform\Doctrine\Orm\Util\QueryNameGeneratorInterface; | ||||
| use ApiPlatform\Metadata\ApiFilter; | use ApiPlatform\Metadata\ApiFilter; | ||||
| use ApiPlatform\Metadata\Operation; | use ApiPlatform\Metadata\Operation; | ||||
| use Doctrine\ORM\Mapping\ClassMetadata; | |||||
| use Doctrine\ORM\QueryBuilder; | use Doctrine\ORM\QueryBuilder; | ||||
| use Doctrine\DBAL\Types\Types; | use Doctrine\DBAL\Types\Types; | ||||
| use Doctrine\ORM\Mapping\ClassMetadataInfo; | use Doctrine\ORM\Mapping\ClassMetadataInfo; | ||||
| @@ -66,12 +67,12 @@ class CustomJsonFilter extends AbstractFilter | |||||
| ->setParameter($parameterName, '%' . $value . '%'); | ->setParameter($parameterName, '%' . $value . '%'); | ||||
| } | } | ||||
| private function isValidProperty(ClassMetadataInfo $metadata, string $property): bool | |||||
| private function isValidProperty(ClassMetadata $metadata, string $property): bool | |||||
| { | { | ||||
| return $metadata->hasField($property) || $metadata->hasAssociation($property); | return $metadata->hasField($property) || $metadata->hasAssociation($property); | ||||
| } | } | ||||
| private function isAssociation(ClassMetadataInfo $metadata, string $property): bool | |||||
| private function isAssociation(ClassMetadata $metadata, string $property): bool | |||||
| { | { | ||||
| return $metadata->hasAssociation($property); | return $metadata->hasAssociation($property); | ||||
| } | } | ||||
| @@ -56,6 +56,7 @@ class LocationApiToEntityMapper implements MapperInterface | |||||
| $entity->setIsZone($dto->isZone); | $entity->setIsZone($dto->isZone); | ||||
| $entity->setIsPlace($dto->isPlace); | $entity->setIsPlace($dto->isPlace); | ||||
| $entity->setIsPort($dto->isPort); | $entity->setIsPort($dto->isPort); | ||||
| $entity->setIsStartEnd($dto->isStartEnd); | |||||
| if ($dto->zoneIri) { | if ($dto->zoneIri) { | ||||
| $zone = $this->zoneRepository->find($dto->zoneIri->id); | $zone = $this->zoneRepository->find($dto->zoneIri->id); | ||||
| @@ -42,6 +42,7 @@ class LocationEntityToApiMapper implements MapperInterface | |||||
| $dto->isZone = $entity->isZone(); | $dto->isZone = $entity->isZone(); | ||||
| $dto->isPlace = $entity->isPlace(); | $dto->isPlace = $entity->isPlace(); | ||||
| $dto->isPort = $entity->isPort(); | $dto->isPort = $entity->isPort(); | ||||
| $dto->isStartEnd = $entity->isStartEnd(); | |||||
| $dto->createdAt = $entity->getCreatedAt(); | $dto->createdAt = $entity->getCreatedAt(); | ||||
| $dto->zoneIri = $dto->zone = $this->microMapper->map($entity->getZone(), ZoneApi::class, [ | $dto->zoneIri = $dto->zone = $this->microMapper->map($entity->getZone(), ZoneApi::class, [ | ||||
| @@ -74,7 +74,6 @@ class TripApiToEntityMapper implements MapperInterface | |||||
| assert($entity instanceof Trip); | assert($entity instanceof Trip); | ||||
| $entity->setCustomerReference($dto->customerReference); | $entity->setCustomerReference($dto->customerReference); | ||||
| $entity->setCaptainName($dto->captainName); | |||||
| $entity->setStartDate($dto->startDate); | $entity->setStartDate($dto->startDate); | ||||
| $entity->setEndDate($dto->endDate); | $entity->setEndDate($dto->endDate); | ||||
| $entity->setNote($dto->note); | $entity->setNote($dto->note); | ||||
| @@ -39,10 +39,10 @@ class TripEntityToApiMapper implements MapperInterface | |||||
| $dto->dbId = $entity->getId(); | $dto->dbId = $entity->getId(); | ||||
| $dto->pilotageReference = "P-" . $entity->getId() . "-" . $entity->getStartDate()->format('Y'); | $dto->pilotageReference = "P-" . $entity->getId() . "-" . $entity->getStartDate()->format('Y'); | ||||
| $dto->customerReference = $entity->getCustomerReference(); | $dto->customerReference = $entity->getCustomerReference(); | ||||
| $dto->captainName = $entity->getCaptainName(); | |||||
| $dto->startDate = $entity->getStartDate(); | $dto->startDate = $entity->getStartDate(); | ||||
| $dto->endDate = $entity->getEndDate(); | $dto->endDate = $entity->getEndDate(); | ||||
| $dto->note = $entity->getNote(); | $dto->note = $entity->getNote(); | ||||
| $dto->completed = $entity->isCompleted(); | |||||
| $dto->createdAt = $entity->getCreatedAt(); | $dto->createdAt = $entity->getCreatedAt(); | ||||
| // Map related entities | // Map related entities | ||||
| @@ -68,6 +68,8 @@ class TripLocationApiToEntityMapper implements MapperInterface | |||||
| } | } | ||||
| $entity->setIsArrival($dto->isArrival); | $entity->setIsArrival($dto->isArrival); | ||||
| $entity->setIsTransit($dto->isTransit); | |||||
| $entity->setIsDeparture($dto->isDeparture); | |||||
| $entity->setDate($dto->date); | $entity->setDate($dto->date); | ||||
| return $entity; | return $entity; | ||||
| @@ -39,13 +39,15 @@ class TripLocationEntityToApiMapper implements MapperInterface | |||||
| $dto->dbId = $entity->getId(); | $dto->dbId = $entity->getId(); | ||||
| $dto->date = $entity->getDate(); | $dto->date = $entity->getDate(); | ||||
| $dto->isArrival = $entity->isArrival(); | $dto->isArrival = $entity->isArrival(); | ||||
| $dto->isTransit = $entity->isTransit(); | |||||
| $dto->isDeparture = $entity->isDeparture(); | |||||
| $dto->createdAt = $entity->getCreatedAt(); | $dto->createdAt = $entity->getCreatedAt(); | ||||
| $dto->trip = $this->microMapper->map($entity->getTrip(), TripApi::class, [ | |||||
| $dto->tripIri = $dto->trip = $this->microMapper->map($entity->getTrip(), TripApi::class, [ | |||||
| MicroMapperInterface::MAX_DEPTH => 5, | MicroMapperInterface::MAX_DEPTH => 5, | ||||
| ]); | ]); | ||||
| $dto->location = $this->microMapper->map($entity->getLocation(), LocationApi::class, [ | |||||
| $dto->locationIri = $dto->location = $this->microMapper->map($entity->getLocation(), LocationApi::class, [ | |||||
| MicroMapperInterface::MAX_DEPTH => 5, | MicroMapperInterface::MAX_DEPTH => 5, | ||||
| ]); | ]); | ||||
| @@ -46,6 +46,7 @@ class UserApiToEntityMapper implements MapperInterface | |||||
| $entity->setFirstName($dto->firstName); | $entity->setFirstName($dto->firstName); | ||||
| $entity->setLastName($dto->lastName); | $entity->setLastName($dto->lastName); | ||||
| $entity->setActive($dto->active); | $entity->setActive($dto->active); | ||||
| $entity->setIsPilot($dto->isPilot); | |||||
| $roles = $entity->getRoles(); | $roles = $entity->getRoles(); | ||||
| if ($dto->isAdmin && !in_array(User::ROLE_ADMIN, $roles, true)) { | if ($dto->isAdmin && !in_array(User::ROLE_ADMIN, $roles, true)) { | ||||
| @@ -46,6 +46,7 @@ class UserEntityToApiMapper implements MapperInterface | |||||
| $dto->roles = $entity->getRoles(); | $dto->roles = $entity->getRoles(); | ||||
| $dto->isAdmin = in_array(User::ROLE_ADMIN, $entity->getRoles(), true); | $dto->isAdmin = in_array(User::ROLE_ADMIN, $entity->getRoles(), true); | ||||
| $dto->active = $entity->isActive(); | $dto->active = $entity->isActive(); | ||||
| $dto->isPilot = $entity->isPilot(); | |||||
| $dto->imageIri = $dto->image = null; | $dto->imageIri = $dto->image = null; | ||||
| if ($entity->getImage() !== null) { | if ($entity->getImage() !== null) { | ||||
| @@ -70,6 +70,7 @@ class UserTripApiToEntityMapper implements MapperInterface | |||||
| $entity->setCompletedDate(new \DateTimeImmutable()); | $entity->setCompletedDate(new \DateTimeImmutable()); | ||||
| } | } | ||||
| $entity->setCompleted($dto->completed); | $entity->setCompleted($dto->completed); | ||||
| $entity->setApproved($dto->approved); | |||||
| if ($dto->signatureIri) { | if ($dto->signatureIri) { | ||||
| $signature = $this->mediaObjectRepository->find($dto->signatureIri->id); | $signature = $this->mediaObjectRepository->find($dto->signatureIri->id); | ||||
| @@ -43,6 +43,7 @@ class UserTripEntityToApiMapper implements MapperInterface | |||||
| $dto->captainName = $entity->getCaptainName(); | $dto->captainName = $entity->getCaptainName(); | ||||
| $dto->signatureUrl = $this->fileUrlService->getFileUrl($entity->getSignature()); | $dto->signatureUrl = $this->fileUrlService->getFileUrl($entity->getSignature()); | ||||
| $dto->completed = $entity->isCompleted(); | $dto->completed = $entity->isCompleted(); | ||||
| $dto->approved = $entity->isApproved(); | |||||
| $dto->completedDate = $entity->getCompletedDate(); | $dto->completedDate = $entity->getCompletedDate(); | ||||
| $dto->createdAt = $entity->getCreatedAt(); | $dto->createdAt = $entity->getCreatedAt(); | ||||
| @@ -8,7 +8,6 @@ use App\Repository\VesselRepository; | |||||
| use App\Repository\ShippingCompanyRepository; | use App\Repository\ShippingCompanyRepository; | ||||
| use Symfonycasts\MicroMapper\AsMapper; | use Symfonycasts\MicroMapper\AsMapper; | ||||
| use Symfonycasts\MicroMapper\MapperInterface; | use Symfonycasts\MicroMapper\MapperInterface; | ||||
| use Symfonycasts\MicroMapper\MicroMapperInterface; | |||||
| #[AsMapper(from: VesselApi::class, to: Vessel::class)] | #[AsMapper(from: VesselApi::class, to: Vessel::class)] | ||||
| class VesselApiToEntityMapper implements MapperInterface | class VesselApiToEntityMapper implements MapperInterface | ||||
| @@ -54,6 +53,12 @@ class VesselApiToEntityMapper implements MapperInterface | |||||
| $entity->setName($dto->name); | $entity->setName($dto->name); | ||||
| $entity->setCode($dto->code); | $entity->setCode($dto->code); | ||||
| $entity->setLength($dto->length); | |||||
| $entity->setBreadth($dto->breadth); | |||||
| $entity->setDraft($dto->draft); | |||||
| $entity->setGrossTonnage($dto->grossTonnage); | |||||
| $entity->setImoNo($dto->imoNo); | |||||
| $entity->setCallSign($dto->callSign); | |||||
| $dto->createdAt = $entity->getCreatedAt(); | $dto->createdAt = $entity->getCreatedAt(); | ||||
| return $entity; | return $entity; | ||||
| @@ -38,9 +38,15 @@ class VesselEntityToApiMapper implements MapperInterface | |||||
| $dto->dbId = $entity->getId(); | $dto->dbId = $entity->getId(); | ||||
| $dto->name = $entity->getName(); | $dto->name = $entity->getName(); | ||||
| $dto->code = $entity->getCode(); | $dto->code = $entity->getCode(); | ||||
| $dto->length = $entity->getLength(); | |||||
| $dto->breadth = $entity->getBreadth(); | |||||
| $dto->draft = $entity->getDraft(); | |||||
| $dto->grossTonnage = $entity->getGrossTonnage(); | |||||
| $dto->imoNo = $entity->getImoNo(); | |||||
| $dto->callSign = $entity->getCallSign(); | |||||
| $dto->createdAt = $entity->getCreatedAt(); | $dto->createdAt = $entity->getCreatedAt(); | ||||
| $dto->company = $this->microMapper->map($entity->getCompany(), ShippingCompanyApi::class, [ | |||||
| $dto->companyIri = $dto->company = $this->microMapper->map($entity->getCompany(), ShippingCompanyApi::class, [ | |||||
| MicroMapperInterface::MAX_DEPTH => 5, | MicroMapperInterface::MAX_DEPTH => 5, | ||||
| ]); | ]); | ||||