172 lines
5.4 KiB
TypeScript
172 lines
5.4 KiB
TypeScript
import { Component, EventEmitter, inject, Input, Output } from '@angular/core';
|
|
import { FormGroup, FormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
|
|
import { finalize, Subject, takeUntil } from 'rxjs';
|
|
import { Country } from '../../core/models/country';
|
|
import { CommonService } from '../../core/services/common/common.service';
|
|
import { Replacement } from '../../core/models/carnet/replacement';
|
|
import { ReplacementService } from '../../core/services/carnet/replacement.service';
|
|
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
|
|
import { NotificationService } from '../../core/services/common/notification.service';
|
|
import { CommonModule } from '@angular/common';
|
|
import { AngularMaterialModule } from '../../shared/module/angular-material.module';
|
|
import { ExtensionReason } from '../../core/models/extension-reason';
|
|
|
|
@Component({
|
|
selector: 'app-replacement-set',
|
|
imports: [AngularMaterialModule, CommonModule, ReactiveFormsModule],
|
|
templateUrl: './replacement-set.component.html',
|
|
styleUrl: './replacement-set.component.scss'
|
|
})
|
|
export class ReplacementSetComponent {
|
|
@Input() headerid: number = 0;
|
|
@Input() isViewMode = false;
|
|
@Input() isEditMode: boolean = false;
|
|
@Output() completed = new EventEmitter<boolean>();
|
|
|
|
extensionForm: FormGroup;
|
|
countries: Country[] = [];
|
|
extensionReasons: ExtensionReason[] = [];
|
|
replacementDetails: Replacement | undefined;
|
|
|
|
// UI state
|
|
isEditing = false;
|
|
isLoading = false;
|
|
changeInProgress = false;
|
|
|
|
private destroy$ = new Subject<void>();
|
|
|
|
private fb = inject(FormBuilder);
|
|
private commonService = inject(CommonService);
|
|
private notificationService = inject(NotificationService);
|
|
private replacementService = inject(ReplacementService);
|
|
private errorHandler = inject(ApiErrorHandlerService);
|
|
|
|
constructor(
|
|
) {
|
|
this.extensionForm = this.createForm();
|
|
}
|
|
|
|
ngOnInit(): void {
|
|
this.loadCountries();
|
|
this.loadExtensionReasons();
|
|
|
|
if (this.headerid > 0) {
|
|
this.isLoading = true;
|
|
this.replacementService.getExtensionData(this.headerid).pipe(finalize(() => {
|
|
this.isLoading = false;
|
|
})).subscribe({
|
|
next: (replacementData: Replacement) => {
|
|
if (replacementData) {
|
|
this.patchFormData(replacementData);
|
|
this.replacementDetails = replacementData;
|
|
this.completed.emit(this.extensionForm.valid || this.extensionForm.disabled);
|
|
}
|
|
},
|
|
error: (error: any) => {
|
|
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load extension details');
|
|
this.notificationService.showError(errorMessage);
|
|
console.error('Error loading extension details:', error);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
ngOnDestroy(): void {
|
|
this.destroy$.next();
|
|
this.destroy$.complete();
|
|
}
|
|
|
|
patchFormData(data: Replacement): void {
|
|
this.extensionForm.patchValue({
|
|
portName: data.portName,
|
|
portCountry: data.portCountry,
|
|
reasonForExtension: data.reasonForExtension,
|
|
duration: data.duration
|
|
});
|
|
|
|
if (this.isViewMode) {
|
|
this.extensionForm.disable();
|
|
}
|
|
}
|
|
|
|
createForm(): FormGroup {
|
|
return this.fb.group({
|
|
portName: [''],
|
|
portCountry: [''],
|
|
reasonForExtension: ['', Validators.required],
|
|
duration: ['', [Validators.max(12)]]
|
|
});
|
|
}
|
|
|
|
loadCountries(): void {
|
|
this.commonService.getCountries()
|
|
.pipe(takeUntil(this.destroy$))
|
|
.subscribe({
|
|
next: (countries) => {
|
|
this.countries = countries;
|
|
},
|
|
error: (error) => {
|
|
console.error('Failed to load countries', error);
|
|
}
|
|
});
|
|
}
|
|
|
|
loadExtensionReasons(): void {
|
|
this.commonService.getExtensionReasons()
|
|
.pipe(takeUntil(this.destroy$))
|
|
.subscribe({
|
|
next: (extensionReasons) => {
|
|
this.extensionReasons = extensionReasons;
|
|
},
|
|
error: (error) => {
|
|
console.error('Failed to load extension reasons', error);
|
|
}
|
|
});
|
|
}
|
|
|
|
onSubmit(): void {
|
|
if (this.extensionForm.invalid) {
|
|
this.extensionForm.markAllAsTouched();
|
|
return;
|
|
}
|
|
|
|
const formData = this.extensionForm.value;
|
|
this.changeInProgress = true;
|
|
|
|
this.replacementService.saveExtensionDetails(this.headerid, formData).pipe(finalize(() => {
|
|
this.changeInProgress = false;
|
|
})).subscribe({
|
|
next: () => {
|
|
this.notificationService.showSuccess('Extension details saved successfully');
|
|
this.completed.emit(this.extensionForm.valid);
|
|
},
|
|
error: (error) => {
|
|
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to save extension information');
|
|
this.notificationService.showError(errorMessage);
|
|
console.error('Error saving extension information:', error);
|
|
}
|
|
});
|
|
}
|
|
|
|
get f() {
|
|
return this.extensionForm.controls;
|
|
}
|
|
|
|
getAddressLabel(): string {
|
|
if (!this.replacementDetails) {
|
|
return 'No contact information available';
|
|
}
|
|
|
|
// Build name parts, filtering out null/undefined/empty strings
|
|
const allParts = [
|
|
this.replacementDetails.address1,
|
|
this.replacementDetails.address2,
|
|
this.replacementDetails.city,
|
|
this.replacementDetails.state,
|
|
this.replacementDetails.country,
|
|
this.replacementDetails.zip
|
|
].filter(part => part != null && part.trim() !== '');
|
|
|
|
return allParts.join(', ') || '';
|
|
}
|
|
} |