feedback updates
This commit is contained in:
parent
d7318a0316
commit
3d07921cec
@ -41,8 +41,7 @@
|
|||||||
<mat-step [completed]="stepsCompleted.shipping" [editable]="stepsCompleted.applicationDetail">
|
<mat-step [completed]="stepsCompleted.shipping" [editable]="stepsCompleted.applicationDetail">
|
||||||
<ng-template matStepLabel>Shipping & Payment</ng-template>
|
<ng-template matStepLabel>Shipping & Payment</ng-template>
|
||||||
<app-shipping (completed)="onShippingSaved($event)" [headerid]="headerid"
|
<app-shipping (completed)="onShippingSaved($event)" [headerid]="headerid"
|
||||||
[applicationName]="applicationName" [enableSubmitButton]="allSectionsCompleted"
|
[applicationName]="applicationName" [enableSubmitButton]="allSectionsCompleted">
|
||||||
[refreshShippingData]="refreshShippingData">
|
|
||||||
</app-shipping>
|
</app-shipping>
|
||||||
</mat-step>
|
</mat-step>
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { Component, inject } from '@angular/core';
|
import { Component, inject, ViewChild } from '@angular/core';
|
||||||
import { ReactiveFormsModule } from '@angular/forms';
|
import { ReactiveFormsModule } from '@angular/forms';
|
||||||
import { AngularMaterialModule } from '../../shared/module/angular-material.module';
|
import { AngularMaterialModule } from '../../shared/module/angular-material.module';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
@ -27,7 +27,6 @@ export class AddCarnetComponent {
|
|||||||
headerid: number = 0;
|
headerid: number = 0;
|
||||||
applicationName: string = '';
|
applicationName: string = '';
|
||||||
userPreferences: UserPreferences;
|
userPreferences: UserPreferences;
|
||||||
refreshShippingData: boolean = false;
|
|
||||||
allSectionsCompleted: boolean = false;
|
allSectionsCompleted: boolean = false;
|
||||||
|
|
||||||
// Track completion of each step
|
// Track completion of each step
|
||||||
@ -39,6 +38,9 @@ export class AddCarnetComponent {
|
|||||||
shipping: false
|
shipping: false
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ViewChild(ShippingComponent, { static: false })
|
||||||
|
private shippingComponent!: ShippingComponent;
|
||||||
|
|
||||||
constructor(userPrefenceService: UserPreferencesService) {
|
constructor(userPrefenceService: UserPreferencesService) {
|
||||||
this.userPreferences = userPrefenceService.getPreferences();
|
this.userPreferences = userPrefenceService.getPreferences();
|
||||||
}
|
}
|
||||||
@ -60,7 +62,9 @@ export class AddCarnetComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onHolderSelectionUpdated(updated: boolean): void {
|
onHolderSelectionUpdated(updated: boolean): void {
|
||||||
this.refreshShippingData = updated;
|
if (updated) {
|
||||||
|
this.shippingComponent?.refreshShippingData();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onGoodsSectionSaved(completed: boolean): void {
|
onGoodsSectionSaved(completed: boolean): void {
|
||||||
|
|||||||
@ -41,8 +41,7 @@
|
|||||||
<mat-step [completed]="stepsCompleted.shipping" [editable]="stepsCompleted.applicationDetail">
|
<mat-step [completed]="stepsCompleted.shipping" [editable]="stepsCompleted.applicationDetail">
|
||||||
<ng-template matStepLabel>Shipping & Payment</ng-template>
|
<ng-template matStepLabel>Shipping & Payment</ng-template>
|
||||||
<app-shipping (completed)="onShippingSaved($event)" [headerid]="headerid" [isEditMode]="isEditMode"
|
<app-shipping (completed)="onShippingSaved($event)" [headerid]="headerid" [isEditMode]="isEditMode"
|
||||||
[applicationName]="applicationName" [enableSubmitButton]="allSectionsCompleted"
|
[applicationName]="applicationName" [enableSubmitButton]="allSectionsCompleted">
|
||||||
[refreshShippingData]="refreshShippingData">
|
|
||||||
</app-shipping>
|
</app-shipping>
|
||||||
</mat-step>
|
</mat-step>
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { Component, inject } from '@angular/core';
|
import { Component, inject, ViewChild } from '@angular/core';
|
||||||
import { AngularMaterialModule } from '../../shared/module/angular-material.module';
|
import { AngularMaterialModule } from '../../shared/module/angular-material.module';
|
||||||
import { ReactiveFormsModule } from '@angular/forms';
|
import { ReactiveFormsModule } from '@angular/forms';
|
||||||
import { ApplicationComponent } from '../application/application.component';
|
import { ApplicationComponent } from '../application/application.component';
|
||||||
@ -27,9 +27,11 @@ export class EditCarnetComponent {
|
|||||||
headerid: number = 0;
|
headerid: number = 0;
|
||||||
userPreferences: UserPreferences;
|
userPreferences: UserPreferences;
|
||||||
applicationName: string = '';
|
applicationName: string = '';
|
||||||
refreshShippingData: boolean = false;
|
|
||||||
allSectionsCompleted: boolean = false;
|
allSectionsCompleted: boolean = false;
|
||||||
|
|
||||||
|
@ViewChild(ShippingComponent, { static: false })
|
||||||
|
private shippingComponent!: ShippingComponent;
|
||||||
|
|
||||||
// Track completion of each step
|
// Track completion of each step
|
||||||
stepsCompleted = {
|
stepsCompleted = {
|
||||||
applicationDetail: true,
|
applicationDetail: true,
|
||||||
@ -75,7 +77,10 @@ export class EditCarnetComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onHolderSelectionUpdated(updated: boolean): void {
|
onHolderSelectionUpdated(updated: boolean): void {
|
||||||
this.refreshShippingData = updated;
|
if (updated) {
|
||||||
|
this.shippingComponent?.refreshShippingData();
|
||||||
|
}
|
||||||
|
|
||||||
this.isAllSectionsCompleted();
|
this.isAllSectionsCompleted();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -219,7 +219,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<button mat-raised-button color="primary" type="submit" [disabled]="itemForm.invalid">
|
<button mat-raised-button color="primary" type="submit"
|
||||||
|
[disabled]="itemForm.invalid || changeInProgress">
|
||||||
Save
|
Save
|
||||||
</button>
|
</button>
|
||||||
<button mat-button type="button" (click)="cancelEdit()">Cancel</button>
|
<button mat-button type="button" (click)="cancelEdit()">Cancel</button>
|
||||||
@ -228,7 +229,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngIf="!showItemForm" class="form-actions">
|
<div *ngIf="!showItemForm" class="form-actions">
|
||||||
<button mat-raised-button color="primary" (click)="onSubmit()" [disabled]="goodsForm.invalid">
|
<button mat-raised-button color="primary" (click)="onSubmit()"
|
||||||
|
[disabled]="goodsForm.invalid || changeInProgress">
|
||||||
Save
|
Save
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -16,7 +16,7 @@ import { ApiErrorHandlerService } from '../../core/services/common/api-error-han
|
|||||||
import { Country } from '../../core/models/country';
|
import { Country } from '../../core/models/country';
|
||||||
import { UnitOfMeasure } from '../../core/models/unitofmeasure';
|
import { UnitOfMeasure } from '../../core/models/unitofmeasure';
|
||||||
import { CommonService } from '../../core/services/common/common.service';
|
import { CommonService } from '../../core/services/common/common.service';
|
||||||
import { Subject, takeUntil } from 'rxjs';
|
import { finalize, Subject, takeUntil } from 'rxjs';
|
||||||
import { Goods, GoodsItem } from '../../core/models/carnet/goods';
|
import { Goods, GoodsItem } from '../../core/models/carnet/goods';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -47,6 +47,7 @@ export class GoodsComponent {
|
|||||||
isEditing = false;
|
isEditing = false;
|
||||||
currentItem: GoodsItem | null = null;
|
currentItem: GoodsItem | null = null;
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
|
changeInProgress = false;
|
||||||
showItemForm = false;
|
showItemForm = false;
|
||||||
fileToUpload: File | null = null;
|
fileToUpload: File | null = null;
|
||||||
isProcessing = false;
|
isProcessing = false;
|
||||||
@ -84,7 +85,7 @@ export class GoodsComponent {
|
|||||||
weight: [0, [Validators.required, Validators.min(1), Validators.pattern(/^\d+(\.\d{1,4})?$/)]],
|
weight: [0, [Validators.required, Validators.min(1), Validators.pattern(/^\d+(\.\d{1,4})?$/)]],
|
||||||
unitOfMeasure: ['', Validators.required],
|
unitOfMeasure: ['', Validators.required],
|
||||||
value: [0, [Validators.required, Validators.min(1), Validators.pattern(/^\d+(\.\d{1,2})?$/)]],
|
value: [0, [Validators.required, Validators.min(1), Validators.pattern(/^\d+(\.\d{1,2})?$/)]],
|
||||||
countryOfOrigin: ['', Validators.required]
|
countryOfOrigin: ['US', Validators.required]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,18 +99,19 @@ export class GoodsComponent {
|
|||||||
this.loadUnitOfMeasures();
|
this.loadUnitOfMeasures();
|
||||||
|
|
||||||
if (this.headerid > 0) {
|
if (this.headerid > 0) {
|
||||||
this.goodsService.getGoodDetailsByHeaderId(this.headerid).subscribe({
|
this.isLoading = true;
|
||||||
|
this.goodsService.getGoodDetailsByHeaderId(this.headerid).pipe(finalize(() => {
|
||||||
|
this.isLoading = false;
|
||||||
|
})).subscribe({
|
||||||
next: (goodsDetail: Goods) => {
|
next: (goodsDetail: Goods) => {
|
||||||
if (goodsDetail) {
|
if (goodsDetail) {
|
||||||
this.patchFormData(goodsDetail);
|
this.patchFormData(goodsDetail);
|
||||||
this.completed.emit(this.goodsForm.valid && this.dataSource.data.length > 0);
|
this.completed.emit(this.goodsForm.valid && this.dataSource.data.length > 0);
|
||||||
}
|
}
|
||||||
this.isLoading = false;
|
|
||||||
},
|
},
|
||||||
error: (error: any) => {
|
error: (error: any) => {
|
||||||
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load good details');
|
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load good details');
|
||||||
this.notificationService.showError(errorMessage);
|
this.notificationService.showError(errorMessage);
|
||||||
this.isLoading = false;
|
|
||||||
console.error('Error loading good details:', error);
|
console.error('Error loading good details:', error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -121,23 +123,23 @@ export class GoodsComponent {
|
|||||||
loadGoodsItems(): void {
|
loadGoodsItems(): void {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
|
|
||||||
this.goodsService.getGoodsItemsByHeaderId(this.headerid).subscribe({
|
this.goodsService.getGoodsItemsByHeaderId(this.headerid).pipe(finalize(() => {
|
||||||
|
this.isLoading = false;
|
||||||
|
})).subscribe({
|
||||||
next: (items: GoodsItem[]) => {
|
next: (items: GoodsItem[]) => {
|
||||||
this.dataSource.data = items;
|
this.dataSource.data = items;
|
||||||
this.isLoading = false;
|
|
||||||
this.completed.emit(this.goodsForm.valid && this.dataSource.data.length > 0);
|
this.completed.emit(this.goodsForm.valid && this.dataSource.data.length > 0);
|
||||||
},
|
},
|
||||||
error: (error: any) => {
|
error: (error: any) => {
|
||||||
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load goods items');
|
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load goods items');
|
||||||
this.notificationService.showError(errorMessage);
|
this.notificationService.showError(errorMessage);
|
||||||
this.isLoading = false;
|
|
||||||
console.error('Error loading goods items:', error);
|
console.error('Error loading goods items:', error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
loadCountries(): void {
|
loadCountries(): void {
|
||||||
this.commonService.getCountries(0)
|
this.commonService.getCountries()
|
||||||
.pipe(takeUntil(this.destroy$))
|
.pipe(takeUntil(this.destroy$))
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: (countries) => {
|
next: (countries) => {
|
||||||
@ -145,7 +147,6 @@ export class GoodsComponent {
|
|||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
console.error('Failed to load countries', error);
|
console.error('Failed to load countries', error);
|
||||||
this.isLoading = false;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -156,11 +157,9 @@ export class GoodsComponent {
|
|||||||
.subscribe({
|
.subscribe({
|
||||||
next: (units) => {
|
next: (units) => {
|
||||||
this.unitsOfMeasures = units;
|
this.unitsOfMeasures = units;
|
||||||
this.isLoading = false;
|
|
||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
console.error('Failed to load unit of measures', error);
|
console.error('Failed to load unit of measures', error);
|
||||||
this.isLoading = false;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -184,7 +183,8 @@ export class GoodsComponent {
|
|||||||
this.itemForm.reset({
|
this.itemForm.reset({
|
||||||
pieces: 0,
|
pieces: 0,
|
||||||
weight: 0,
|
weight: 0,
|
||||||
value: 0
|
value: 0,
|
||||||
|
countryOfOrigin: 'US',
|
||||||
});
|
});
|
||||||
this.itemForm.markAsUntouched();
|
this.itemForm.markAsUntouched();
|
||||||
}
|
}
|
||||||
@ -220,11 +220,15 @@ export class GoodsComponent {
|
|||||||
let itemDataArray: GoodsItem[] = [];
|
let itemDataArray: GoodsItem[] = [];
|
||||||
itemDataArray.push(itemData);
|
itemDataArray.push(itemData);
|
||||||
|
|
||||||
|
this.changeInProgress = true;
|
||||||
|
|
||||||
const saveObservable = this.isEditing && this.currentItem
|
const saveObservable = this.isEditing && this.currentItem
|
||||||
? this.goodsService.updateGoodsItem(this.headerid, itemDataArray)
|
? this.goodsService.updateGoodsItem(this.headerid, itemDataArray)
|
||||||
: this.goodsService.addGoodsItem(this.headerid, itemDataArray);
|
: this.goodsService.addGoodsItem(this.headerid, itemDataArray);
|
||||||
|
|
||||||
saveObservable.subscribe({
|
saveObservable.pipe(finalize(() => {
|
||||||
|
this.changeInProgress = false;
|
||||||
|
})).subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
this.notificationService.showSuccess(`Goods ${this.isEditing ? 'updated' : 'added'} successfully`);
|
this.notificationService.showSuccess(`Goods ${this.isEditing ? 'updated' : 'added'} successfully`);
|
||||||
this.loadGoodsItems();
|
this.loadGoodsItems();
|
||||||
@ -275,10 +279,10 @@ export class GoodsComponent {
|
|||||||
const file: File = event.target.files[0];
|
const file: File = event.target.files[0];
|
||||||
|
|
||||||
this.processExcelFile(file)
|
this.processExcelFile(file)
|
||||||
.then(response => {
|
// .then(response => {
|
||||||
console.log('File uploaded successfully:', response);
|
// // console.log('File uploaded successfully:', response);
|
||||||
// Handle success (e.g., update UI)
|
// // Handle success (e.g., update UI)
|
||||||
})
|
// })
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.error('Error processing file:', error);
|
console.error('Error processing file:', error);
|
||||||
this.notificationService.showError('Failed to upload file');
|
this.notificationService.showError('Failed to upload file');
|
||||||
@ -319,7 +323,10 @@ export class GoodsComponent {
|
|||||||
// item.unitOfMeasure = this.getUnitOfMeasureValue(item.unitOfMeasure);
|
// item.unitOfMeasure = this.getUnitOfMeasureValue(item.unitOfMeasure);
|
||||||
// });
|
// });
|
||||||
|
|
||||||
this.goodsService.addGoodsItem(this.headerid, items).subscribe({
|
this.changeInProgress = true;
|
||||||
|
this.goodsService.addGoodsItem(this.headerid, items).pipe(finalize(() => {
|
||||||
|
this.changeInProgress = false;
|
||||||
|
})).subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
this.notificationService.showSuccess(`Goods uploaded successfully`);
|
this.notificationService.showSuccess(`Goods uploaded successfully`);
|
||||||
this.loadGoodsItems();
|
this.loadGoodsItems();
|
||||||
@ -390,9 +397,11 @@ export class GoodsComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const formData = this.goodsForm.value;
|
const formData = this.goodsForm.value;
|
||||||
this.isLoading = true;
|
this.changeInProgress = true;
|
||||||
|
|
||||||
this.goodsService.saveGoodsData(this.headerid, formData).subscribe({
|
this.goodsService.saveGoodsData(this.headerid, formData).pipe(finalize(() => {
|
||||||
|
this.changeInProgress = false;
|
||||||
|
})).subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
this.notificationService.showSuccess('Goods information saved successfully');
|
this.notificationService.showSuccess('Goods information saved successfully');
|
||||||
this.completed.emit(this.goodsForm.valid && this.dataSource.data.length > 0);
|
this.completed.emit(this.goodsForm.valid && this.dataSource.data.length > 0);
|
||||||
@ -401,9 +410,6 @@ export class GoodsComponent {
|
|||||||
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to save goods information');
|
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to save goods information');
|
||||||
this.notificationService.showError(errorMessage);
|
this.notificationService.showError(errorMessage);
|
||||||
console.error('Error saving goods:', error);
|
console.error('Error saving goods:', error);
|
||||||
},
|
|
||||||
complete: () => {
|
|
||||||
this.isLoading = false;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,8 @@
|
|||||||
<div class="shipping-container">
|
<div class="shipping-container">
|
||||||
|
<div class="loading-shade" *ngIf="isLoading">
|
||||||
|
<mat-spinner diameter="50"></mat-spinner>
|
||||||
|
</div>
|
||||||
|
|
||||||
<form [formGroup]="shippingForm" (ngSubmit)="onSubmit()">
|
<form [formGroup]="shippingForm" (ngSubmit)="onSubmit()">
|
||||||
<!-- Insurance Section -->
|
<!-- Insurance Section -->
|
||||||
<div class="section">
|
<div class="section">
|
||||||
@ -344,9 +348,9 @@
|
|||||||
<span>Submit Application</span>
|
<span>Submit Application</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button mat-raised-button color="primary" type="submit" [disabled]="shippingForm.invalid || isLoading">
|
<button mat-raised-button color="primary" type="submit"
|
||||||
<span *ngIf="!isLoading">Save</span>
|
[disabled]="shippingForm.invalid || changeInProgress">
|
||||||
<mat-spinner *ngIf="isLoading" diameter="24"></mat-spinner>
|
Save
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { Component, EventEmitter, inject, Input, Output, SimpleChanges } from '@angular/core';
|
import { Component, EventEmitter, inject, Input, Output } from '@angular/core';
|
||||||
import { ReactiveFormsModule, FormBuilder, FormGroup, Validators } from '@angular/forms';
|
import { ReactiveFormsModule, FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||||
import { NotificationService } from '../../core/services/common/notification.service';
|
import { NotificationService } from '../../core/services/common/notification.service';
|
||||||
import { AngularMaterialModule } from '../../shared/module/angular-material.module';
|
import { AngularMaterialModule } from '../../shared/module/angular-material.module';
|
||||||
@ -34,7 +34,6 @@ import { FormOfSecurity } from '../../core/models/formofsecurity';
|
|||||||
export class ShippingComponent {
|
export class ShippingComponent {
|
||||||
@Input() headerid: number = 0;
|
@Input() headerid: number = 0;
|
||||||
@Input() isEditMode = false;
|
@Input() isEditMode = false;
|
||||||
@Input() refreshShippingData = false;
|
|
||||||
@Input() enableSubmitButton = false;
|
@Input() enableSubmitButton = false;
|
||||||
@Input() applicationName: string = '';
|
@Input() applicationName: string = '';
|
||||||
|
|
||||||
@ -53,6 +52,7 @@ export class ShippingComponent {
|
|||||||
|
|
||||||
shippingForm: FormGroup;
|
shippingForm: FormGroup;
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
|
changeInProgress = false;
|
||||||
showAddressForm = false;
|
showAddressForm = false;
|
||||||
showContactForm = false;
|
showContactForm = false;
|
||||||
deliveryEstimate: string = '';
|
deliveryEstimate: string = '';
|
||||||
@ -91,7 +91,7 @@ export class ShippingComponent {
|
|||||||
address2: [''],
|
address2: [''],
|
||||||
city: [''],
|
city: [''],
|
||||||
state: [''],
|
state: [''],
|
||||||
country: [''],
|
country: ['US'],
|
||||||
zip: [''],
|
zip: [''],
|
||||||
}),
|
}),
|
||||||
contact: this.fb.group({
|
contact: this.fb.group({
|
||||||
@ -142,7 +142,7 @@ export class ShippingComponent {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.isLoading = true;
|
this.changeInProgress = true;
|
||||||
const shippingData: Shipping = this.shippingForm.value;
|
const shippingData: Shipping = this.shippingForm.value;
|
||||||
|
|
||||||
if (shippingData.shipTo !== '3RDPARTY') {
|
if (shippingData.shipTo !== '3RDPARTY') {
|
||||||
@ -150,16 +150,16 @@ export class ShippingComponent {
|
|||||||
shippingData.contact = shippingData.shipTo === 'PREPARER' ? this.preparerContact ?? undefined : this.holderContact ?? undefined;
|
shippingData.contact = shippingData.shipTo === 'PREPARER' ? this.preparerContact ?? undefined : this.holderContact ?? undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.shippingService.saveShippingDetails(this.headerid, shippingData).subscribe({
|
this.shippingService.saveShippingDetails(this.headerid, shippingData).pipe(finalize(() => {
|
||||||
|
this.changeInProgress = false;
|
||||||
|
})).subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
this.notificationService.showSuccess('Shipping & payments information saved successfully');
|
this.notificationService.showSuccess('Shipping & payments information saved successfully');
|
||||||
this.completed.emit(true);
|
this.completed.emit(true);
|
||||||
this.isLoading = false;
|
|
||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to save shipping and payment information');
|
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to save shipping and payment information');
|
||||||
this.notificationService.showError(errorMessage);
|
this.notificationService.showError(errorMessage);
|
||||||
this.isLoading = false;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -188,8 +188,8 @@ export class ShippingComponent {
|
|||||||
this.shippingForm.get('address.zip')?.updateValueAndValidity();
|
this.shippingForm.get('address.zip')?.updateValueAndValidity();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges) {
|
public refreshShippingData(): void {
|
||||||
if (changes['refreshShippingData'] && this.headerid > 0) {
|
if (this.headerid > 0) {
|
||||||
this.loadShippingData();
|
this.loadShippingData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -209,7 +209,8 @@ export class ShippingComponent {
|
|||||||
|
|
||||||
cancelEditAddressForm(): void {
|
cancelEditAddressForm(): void {
|
||||||
this.showAddressForm = false;
|
this.showAddressForm = false;
|
||||||
this.shippingForm.get('address')?.reset();
|
this.shippingForm.get('address')?.reset({ country: 'US' });
|
||||||
|
this.loadStates('US');
|
||||||
}
|
}
|
||||||
|
|
||||||
onShipToChange(event: any): void {
|
onShipToChange(event: any): void {
|
||||||
@ -221,14 +222,15 @@ export class ShippingComponent {
|
|||||||
|
|
||||||
if (shipTo === '3RDPARTY') {
|
if (shipTo === '3RDPARTY') {
|
||||||
this.shippingForm.get('contact')?.reset();
|
this.shippingForm.get('contact')?.reset();
|
||||||
this.shippingForm.get('address')?.reset();
|
this.shippingForm.get('address')?.reset({ country: 'US' });
|
||||||
|
this.loadStates('US');
|
||||||
this.showAddressForm = true;
|
this.showAddressForm = true;
|
||||||
this.showContactForm = true;
|
this.showContactForm = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
loadCountries(): void {
|
loadCountries(): void {
|
||||||
this.commonService.getCountries(0)
|
this.commonService.getCountries()
|
||||||
.pipe(takeUntil(this.destroy$))
|
.pipe(takeUntil(this.destroy$))
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: (countries) => {
|
next: (countries) => {
|
||||||
@ -236,13 +238,12 @@ export class ShippingComponent {
|
|||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
console.error('Failed to load countries', error);
|
console.error('Failed to load countries', error);
|
||||||
this.isLoading = false;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
loadDeliveryTypes(): void {
|
loadDeliveryTypes(): void {
|
||||||
this.commonService.getDeliveryTypes(0)
|
this.commonService.getDeliveryTypes()
|
||||||
.pipe(takeUntil(this.destroy$))
|
.pipe(takeUntil(this.destroy$))
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: (deliveryTypes) => {
|
next: (deliveryTypes) => {
|
||||||
@ -250,13 +251,12 @@ export class ShippingComponent {
|
|||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
console.error('Failed to load delivery types', error);
|
console.error('Failed to load delivery types', error);
|
||||||
this.isLoading = false;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
loadDeliveryMethods(): void {
|
loadDeliveryMethods(): void {
|
||||||
this.commonService.getDeliveryMethods(0)
|
this.commonService.getDeliveryMethods()
|
||||||
.pipe(takeUntil(this.destroy$))
|
.pipe(takeUntil(this.destroy$))
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: (deliveryMethods) => {
|
next: (deliveryMethods) => {
|
||||||
@ -264,13 +264,12 @@ export class ShippingComponent {
|
|||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
console.error('Failed to load delivery methods', error);
|
console.error('Failed to load delivery methods', error);
|
||||||
this.isLoading = false;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
loadPaymentTypes(): void {
|
loadPaymentTypes(): void {
|
||||||
this.commonService.getPaymentTypes(0)
|
this.commonService.getPaymentTypes()
|
||||||
.pipe(takeUntil(this.destroy$))
|
.pipe(takeUntil(this.destroy$))
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: (paymentTypes) => {
|
next: (paymentTypes) => {
|
||||||
@ -278,7 +277,6 @@ export class ShippingComponent {
|
|||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
console.error('Failed to load payment types', error);
|
console.error('Failed to load payment types', error);
|
||||||
this.isLoading = false;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -286,29 +284,29 @@ export class ShippingComponent {
|
|||||||
loadStates(country: string): void {
|
loadStates(country: string): void {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
country = this.countriesHasStates.includes(country) ? country : 'FN';
|
country = this.countriesHasStates.includes(country) ? country : 'FN';
|
||||||
this.commonService.getStates(country, 0)
|
this.commonService.getStates(country)
|
||||||
.pipe(takeUntil(this.destroy$))
|
.pipe(takeUntil(this.destroy$),
|
||||||
.subscribe({
|
finalize(() => {
|
||||||
next: (states) => {
|
this.isLoading = false;
|
||||||
this.states = states;
|
})).subscribe({
|
||||||
const stateControl = this.shippingForm.get('contact.state');
|
next: (states) => {
|
||||||
if (this.countriesHasStates.includes(country)) {
|
this.states = states;
|
||||||
stateControl?.enable();
|
const stateControl = this.shippingForm.get('contact.state');
|
||||||
} else {
|
if (this.countriesHasStates.includes(country)) {
|
||||||
stateControl?.disable();
|
stateControl?.enable();
|
||||||
stateControl?.setValue('FN');
|
} else {
|
||||||
|
stateControl?.disable();
|
||||||
|
stateControl?.setValue('FN');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: (error) => {
|
||||||
|
console.error('Failed to load states', error);
|
||||||
}
|
}
|
||||||
this.isLoading = false;
|
});
|
||||||
},
|
|
||||||
error: (error) => {
|
|
||||||
console.error('Failed to load states', error);
|
|
||||||
this.isLoading = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
loadFormOfSecurities(): void {
|
loadFormOfSecurities(): void {
|
||||||
this.commonService.getFormOfSecurities(0)
|
this.commonService.getFormOfSecurities()
|
||||||
.pipe(takeUntil(this.destroy$))
|
.pipe(takeUntil(this.destroy$))
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: (fos) => {
|
next: (fos) => {
|
||||||
@ -483,11 +481,11 @@ export class ShippingComponent {
|
|||||||
} else if (key === 'title') {
|
} else if (key === 'title') {
|
||||||
contactGroup.get(key)?.setValidators([Validators.required, Validators.maxLength(100)]);
|
contactGroup.get(key)?.setValidators([Validators.required, Validators.maxLength(100)]);
|
||||||
} else if (key === 'phone') {
|
} else if (key === 'phone') {
|
||||||
contactGroup.get(key)?.setValidators([Validators.required, Validators.pattern(/^[0-9]{10,15}$/)]);
|
contactGroup.get(key)?.setValidators([Validators.required, Validators.pattern(/^[0-9\-\(\)]{10,15}$/)]);
|
||||||
} else if (key === 'mobile') {
|
} else if (key === 'mobile') {
|
||||||
contactGroup.get(key)?.setValidators([Validators.required, Validators.pattern(/^[0-9]{10,15}$/)]);
|
contactGroup.get(key)?.setValidators([Validators.required, Validators.pattern(/^[0-9\-\(\)]{10,15}$/)]);
|
||||||
} else if (key === 'fax') {
|
} else if (key === 'fax') {
|
||||||
contactGroup.get(key)?.setValidators([Validators.pattern(/^[0-9]{10,15}$/)]);
|
contactGroup.get(key)?.setValidators([Validators.pattern(/^[0-9\-\(\)]{10,15}$/)]);
|
||||||
} else if (key === 'email') {
|
} else if (key === 'email') {
|
||||||
contactGroup.get(key)?.setValidators([Validators.required, Validators.email, Validators.maxLength(100)]);
|
contactGroup.get(key)?.setValidators([Validators.required, Validators.email, Validators.maxLength(100)]);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -102,7 +102,8 @@
|
|||||||
<mat-divider></mat-divider>
|
<mat-divider></mat-divider>
|
||||||
|
|
||||||
<mat-card-actions align="end">
|
<mat-card-actions align="end">
|
||||||
<button mat-raised-button color="primary" (click)="onAccept()" [disabled]="!hasReadAllTerms">
|
<button mat-raised-button color="primary" (click)="onAccept()"
|
||||||
|
[disabled]="!hasReadAllTerms || changeInProgress">
|
||||||
Accept
|
Accept
|
||||||
</button>
|
</button>
|
||||||
<button mat-button (click)="onDecline()">Decline</button>
|
<button mat-button (click)="onDecline()">Decline</button>
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import { NotificationService } from '../../core/services/common/notification.ser
|
|||||||
import { StorageService } from '../../core/services/common/storage.service';
|
import { StorageService } from '../../core/services/common/storage.service';
|
||||||
import { CarnetService } from '../../core/services/carnet/carnet.service';
|
import { CarnetService } from '../../core/services/carnet/carnet.service';
|
||||||
import { Fees } from '../../core/models/carnet/fee';
|
import { Fees } from '../../core/models/carnet/fee';
|
||||||
|
import { finalize } from 'rxjs';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-terms-conditions',
|
selector: 'app-terms-conditions',
|
||||||
@ -29,7 +30,7 @@ export class TermsConditionsComponent {
|
|||||||
currentDate = new Date();
|
currentDate = new Date();
|
||||||
hasReadAllTerms = false;
|
hasReadAllTerms = false;
|
||||||
currentApplicationDetails: { headerid: number, applicationName: string } | null = null;
|
currentApplicationDetails: { headerid: number, applicationName: string } | null = null;
|
||||||
isLoading: boolean = false;
|
changeInProgress: boolean = false;
|
||||||
estimatedFees: Fees = {};
|
estimatedFees: Fees = {};
|
||||||
|
|
||||||
private notificationService = inject(NotificationService);
|
private notificationService = inject(NotificationService);
|
||||||
@ -61,19 +62,19 @@ export class TermsConditionsComponent {
|
|||||||
|
|
||||||
onAccept(): void {
|
onAccept(): void {
|
||||||
|
|
||||||
this.isLoading = true;
|
this.changeInProgress = true;
|
||||||
this.carnetService.submitApplication(this.currentApplicationDetails?.headerid!).subscribe({
|
this.carnetService.submitApplication(this.currentApplicationDetails?.headerid!).pipe(finalize(() => {
|
||||||
|
this.changeInProgress = false;
|
||||||
|
})).subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
this.notificationService.showSuccess('Application submitted successfully');
|
this.notificationService.showSuccess('Application submitted successfully');
|
||||||
this.storageService.removeItem('currentapplication');
|
this.storageService.removeItem('currentapplication');
|
||||||
this.navigationService.navigate(["home"]);
|
this.navigationService.navigate(["home"]);
|
||||||
this.isLoading = false;
|
|
||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to submit application');
|
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to submit application');
|
||||||
this.notificationService.showError(errorMessage);
|
this.notificationService.showError(errorMessage);
|
||||||
console.error('Error submitting the application', error);
|
console.error('Error submitting the application', error);
|
||||||
this.isLoading = false;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,7 @@
|
|||||||
<div class="travel-plan-container">
|
<div class="travel-plan-container">
|
||||||
|
<div class="loading-shade" *ngIf="isLoading">
|
||||||
|
<mat-spinner diameter="50"></mat-spinner>
|
||||||
|
</div>
|
||||||
<form [formGroup]="travelForm" (ngSubmit)="onSubmit()">
|
<form [formGroup]="travelForm" (ngSubmit)="onSubmit()">
|
||||||
<!-- USA Entries -->
|
<!-- USA Entries -->
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
@ -139,9 +142,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button mat-raised-button color="primary" type="submit" [disabled]="isLoading">
|
<button mat-raised-button color="primary" type="submit" [disabled]="changeInProgress">
|
||||||
<span *ngIf="!isLoading">Save</span>
|
Save
|
||||||
<mat-spinner *ngIf="isLoading" diameter="24"></mat-spinner>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { Component, EventEmitter, inject, Input, Output, SimpleChanges } from '@angular/core';
|
import { Component, EventEmitter, inject, Input, Output, SimpleChanges } from '@angular/core';
|
||||||
import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
|
import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||||
import { forkJoin } from 'rxjs';
|
import { finalize, forkJoin } from 'rxjs';
|
||||||
import { TravelPlanService } from '../../core/services/carnet/travel-plan.service';
|
import { TravelPlanService } from '../../core/services/carnet/travel-plan.service';
|
||||||
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
|
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
|
||||||
import { NotificationService } from '../../core/services/common/notification.service';
|
import { NotificationService } from '../../core/services/common/notification.service';
|
||||||
@ -30,6 +30,7 @@ export class TravelPlanComponent {
|
|||||||
|
|
||||||
travelForm: FormGroup;
|
travelForm: FormGroup;
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
|
changeInProgress = false;
|
||||||
visitsCount = 1;
|
visitsCount = 1;
|
||||||
transitsCount = 1;
|
transitsCount = 1;
|
||||||
|
|
||||||
@ -253,17 +254,17 @@ export class TravelPlanComponent {
|
|||||||
forkJoin({
|
forkJoin({
|
||||||
countries: this.travelPlanService.getCountriesAndMessages(),
|
countries: this.travelPlanService.getCountriesAndMessages(),
|
||||||
travelPlanData: this.travelPlanService.getTravelPlan(this.headerid)
|
travelPlanData: this.travelPlanService.getTravelPlan(this.headerid)
|
||||||
}).subscribe({
|
}).pipe(finalize(() => {
|
||||||
|
this.isLoading = false;
|
||||||
|
})).subscribe({
|
||||||
next: (results) => {
|
next: (results) => {
|
||||||
this.countries = results.countries as Country[];
|
this.countries = results.countries as Country[];
|
||||||
this.patchTravelPlanData(results.travelPlanData);
|
this.patchTravelPlanData(results.travelPlanData);
|
||||||
this.isLoading = false;
|
|
||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
console.error('Error loading travel plan data', error);
|
console.error('Error loading travel plan data', error);
|
||||||
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load travel plan data');
|
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load travel plan data');
|
||||||
this.notificationService.showError(errorMessage);
|
this.notificationService.showError(errorMessage);
|
||||||
this.isLoading = false;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -295,18 +296,19 @@ export class TravelPlanComponent {
|
|||||||
transits: this.selectedTransitCountries
|
transits: this.selectedTransitCountries
|
||||||
};
|
};
|
||||||
|
|
||||||
this.isLoading = true;
|
this.changeInProgress = true;
|
||||||
this.travelPlanService.saveTravelPlan(this.headerid, travelPlan).subscribe({
|
|
||||||
|
this.travelPlanService.saveTravelPlan(this.headerid, travelPlan).pipe(finalize(() => {
|
||||||
|
this.changeInProgress = false;
|
||||||
|
})).subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
this.notificationService.showSuccess('Travel plan saved successfully');
|
this.notificationService.showSuccess('Travel plan saved successfully');
|
||||||
this.completed.emit(true);
|
this.completed.emit(true);
|
||||||
this.isLoading = false;
|
|
||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to save travel plan');
|
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to save travel plan');
|
||||||
this.notificationService.showError(errorMessage);
|
this.notificationService.showError(errorMessage);
|
||||||
console.error('Error saving travel plan data : ', error);
|
console.error('Error saving travel plan data : ', error);
|
||||||
this.isLoading = false;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="copyright">
|
<div class="copyright">
|
||||||
© {{ currentYear }} USCIB Carnet Portal. All rights reserved.
|
© {{ currentYear }} {{currentServiceProviderName}}. All rights reserved.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
@ -1,6 +1,8 @@
|
|||||||
import { Component, Input } from '@angular/core';
|
import { Component, effect, inject, Input } from '@angular/core';
|
||||||
import { AngularMaterialModule } from '../../shared/module/angular-material.module';
|
import { AngularMaterialModule } from '../../shared/module/angular-material.module';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { User } from '../../core/models/user';
|
||||||
|
import { UserService } from '../../core/services/common/user.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-footer',
|
selector: 'app-footer',
|
||||||
@ -10,5 +12,20 @@ import { CommonModule } from '@angular/common';
|
|||||||
})
|
})
|
||||||
export class FooterComponent {
|
export class FooterComponent {
|
||||||
currentYear = new Date().getFullYear();
|
currentYear = new Date().getFullYear();
|
||||||
|
currentServiceProviderName: string = '';
|
||||||
|
userDetails: User | null = {};
|
||||||
|
|
||||||
@Input() isUserLoggedIn = false;
|
@Input() isUserLoggedIn = false;
|
||||||
|
|
||||||
|
private userService = inject(UserService);
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
) {
|
||||||
|
effect(() => {
|
||||||
|
this.userDetails = this.userService.userDetailsSignal();
|
||||||
|
if (this.userDetails?.userDetails) {
|
||||||
|
this.currentServiceProviderName = this.userDetails.userDetails.serviceProviderName || '';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -6,18 +6,7 @@
|
|||||||
|
|
||||||
<div class="navbar-menu">
|
<div class="navbar-menu">
|
||||||
<button mat-button (click)="navigateTo('home')">Home</button>
|
<button mat-button (click)="navigateTo('home')">Home</button>
|
||||||
<button mat-button (click)="navigateTo('usersettings')">User Settings</button>
|
|
||||||
<!--
|
|
||||||
<button mat-icon-button [matMenuTriggerFor]="profile">
|
|
||||||
<mat-icon>account_circle</mat-icon>
|
|
||||||
</button>
|
|
||||||
<mat-menu #profile="matMenu">
|
|
||||||
<button mat-menu-item (click)="logout()">
|
|
||||||
<mat-icon>logout</mat-icon>
|
|
||||||
<span>Logout</span>
|
|
||||||
</button>
|
|
||||||
</mat-menu> -->
|
|
||||||
|
|
||||||
<div class="profile-container">
|
<div class="profile-container">
|
||||||
<button mat-icon-button (click)="toggleProfileMenu()" class="profile-button">
|
<button mat-icon-button (click)="toggleProfileMenu()" class="profile-button">
|
||||||
<mat-icon>account_circle</mat-icon>
|
<mat-icon>account_circle</mat-icon>
|
||||||
@ -29,6 +18,11 @@
|
|||||||
<span>{{ userEmail }}</span>
|
<span>{{ userEmail }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<button mat-menu-item (click)="navigateTo('/usersettings')">
|
||||||
|
<mat-icon>settings</mat-icon>
|
||||||
|
<span>User Preferences</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
<button mat-menu-item (click)="logout()">
|
<button mat-menu-item (click)="logout()">
|
||||||
<mat-icon>logout</mat-icon>
|
<mat-icon>logout</mat-icon>
|
||||||
<span>Logout</span>
|
<span>Logout</span>
|
||||||
|
|||||||
@ -17,4 +17,5 @@ export interface UserDetail {
|
|||||||
urlKey: string;
|
urlKey: string;
|
||||||
logoName: string;
|
logoName: string;
|
||||||
themeName: string;
|
themeName: string;
|
||||||
|
serviceProviderName: string;
|
||||||
}
|
}
|
||||||
@ -16,6 +16,7 @@ import { UnitOfMeasure } from '../../models/unitofmeasure';
|
|||||||
import { DeliveryMethod } from '../../models/delivery-method';
|
import { DeliveryMethod } from '../../models/delivery-method';
|
||||||
import { PaymentType } from '../../models/payment-type';
|
import { PaymentType } from '../../models/payment-type';
|
||||||
import { FormOfSecurity } from '../../models/formofsecurity';
|
import { FormOfSecurity } from '../../models/formofsecurity';
|
||||||
|
import { UserService } from './user.service';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
@ -25,9 +26,10 @@ export class CommonService {
|
|||||||
private apiDb = environment.apiDb;
|
private apiDb = environment.apiDb;
|
||||||
|
|
||||||
private http = inject(HttpClient);
|
private http = inject(HttpClient);
|
||||||
|
private userService = inject(UserService);
|
||||||
|
|
||||||
getCountries(spid: number = 0): Observable<Country[]> {
|
getCountries(): Observable<Country[]> {
|
||||||
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=002&P_SPID=0`).pipe(
|
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=002&P_SPID=${this.userService.getUserSpid()}`).pipe(
|
||||||
map((response) =>
|
map((response) =>
|
||||||
response.map((item) => ({
|
response.map((item) => ({
|
||||||
name: item.PARAMDESC,
|
name: item.PARAMDESC,
|
||||||
@ -38,8 +40,8 @@ export class CommonService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getStates(country: string, spid: number = 0): Observable<State[]> {
|
getStates(country: string): Observable<State[]> {
|
||||||
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=001&P_SPID=0`).pipe(
|
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=001&P_SPID=${this.userService.getUserSpid()}`).pipe(
|
||||||
map((response) =>
|
map((response) =>
|
||||||
response.map((item) => ({
|
response.map((item) => ({
|
||||||
name: item.PARAMDESC,
|
name: item.PARAMDESC,
|
||||||
@ -67,8 +69,8 @@ export class CommonService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getDeliveryTypes(spid: number = 0): Observable<DeliveryType[]> {
|
getDeliveryTypes(): Observable<DeliveryType[]> {
|
||||||
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=006&P_SPID=0`).pipe(
|
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=006&P_SPID=${this.userService.getUserSpid()}`).pipe(
|
||||||
map((response) =>
|
map((response) =>
|
||||||
response.map((item) => ({
|
response.map((item) => ({
|
||||||
name: item.PARAMDESC,
|
name: item.PARAMDESC,
|
||||||
@ -81,8 +83,8 @@ export class CommonService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getTimezones(spid: number = 0): Observable<TimeZone[]> {
|
getTimezones(): Observable<TimeZone[]> {
|
||||||
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=010&P_SPID=0`).pipe(
|
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=010&P_SPID=${this.userService.getUserSpid()}`).pipe(
|
||||||
map((response) =>
|
map((response) =>
|
||||||
response.map((item) => ({
|
response.map((item) => ({
|
||||||
name: item.PARAMDESC,
|
name: item.PARAMDESC,
|
||||||
@ -93,8 +95,8 @@ export class CommonService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getFeeTypes(spid: number = 0): Observable<FeeType[]> {
|
getFeeTypes(): Observable<FeeType[]> {
|
||||||
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=009&P_SPID=0`).pipe(
|
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=009&P_SPID=${this.userService.getUserSpid()}`).pipe(
|
||||||
map((response) =>
|
map((response) =>
|
||||||
response.map((item) => ({
|
response.map((item) => ({
|
||||||
name: item.PARAMDESC,
|
name: item.PARAMDESC,
|
||||||
@ -105,8 +107,8 @@ export class CommonService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getBondSuretys(spid: number = 0): Observable<BondSurety[]> {
|
getBondSuretys(): Observable<BondSurety[]> {
|
||||||
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=003&P_SPID=0`).pipe(
|
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=003&P_SPID=${this.userService.getUserSpid()}`).pipe(
|
||||||
map((response) =>
|
map((response) =>
|
||||||
response.map((item) => ({
|
response.map((item) => ({
|
||||||
name: item.PARAMDESC,
|
name: item.PARAMDESC,
|
||||||
@ -117,8 +119,8 @@ export class CommonService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getCargoPolicies(spid: number = 0): Observable<CargoPolicy[]> {
|
getCargoPolicies(): Observable<CargoPolicy[]> {
|
||||||
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=004&P_SPID=0`).pipe(
|
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=004&P_SPID=${this.userService.getUserSpid()}`).pipe(
|
||||||
map((response) =>
|
map((response) =>
|
||||||
response.map((item) => ({
|
response.map((item) => ({
|
||||||
name: item.PARAMDESC,
|
name: item.PARAMDESC,
|
||||||
@ -129,8 +131,8 @@ export class CommonService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getCargoSuretys(spid: number = 0): Observable<CargoSurety[]> {
|
getCargoSuretys(): Observable<CargoSurety[]> {
|
||||||
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=005&P_SPID=0`).pipe(
|
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=005&P_SPID=${this.userService.getUserSpid()}`).pipe(
|
||||||
map((response) =>
|
map((response) =>
|
||||||
response.map((item) => ({
|
response.map((item) => ({
|
||||||
name: item.PARAMDESC,
|
name: item.PARAMDESC,
|
||||||
@ -141,8 +143,8 @@ export class CommonService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getCarnetStatuses(spid: number = 0): Observable<CarnetStatus[]> {
|
getCarnetStatuses(): Observable<CarnetStatus[]> {
|
||||||
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=011&P_SPID=0`).pipe(
|
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=011&P_SPID=${this.userService.getUserSpid()}`).pipe(
|
||||||
map((response) =>
|
map((response) =>
|
||||||
response.map((item) => ({
|
response.map((item) => ({
|
||||||
name: item.PARAMDESC,
|
name: item.PARAMDESC,
|
||||||
@ -154,8 +156,8 @@ export class CommonService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getUnitOfMeasures(_spid: number = 0): Observable<UnitOfMeasure[]> {
|
getUnitOfMeasures(): Observable<UnitOfMeasure[]> {
|
||||||
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=013&P_SPID=0`).pipe(
|
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=013&P_SPID=${this.userService.getUserSpid()}`).pipe(
|
||||||
map((response) =>
|
map((response) =>
|
||||||
response.map((item) => ({
|
response.map((item) => ({
|
||||||
name: item.PARAMDESC,
|
name: item.PARAMDESC,
|
||||||
@ -166,8 +168,8 @@ export class CommonService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getDeliveryMethods(_spid: number = 0): Observable<DeliveryMethod[]> {
|
getDeliveryMethods(): Observable<DeliveryMethod[]> {
|
||||||
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=007&P_SPID=0`).pipe(
|
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=007&P_SPID=${this.userService.getUserSpid()}`).pipe(
|
||||||
map((response) =>
|
map((response) =>
|
||||||
response.map((item) => ({
|
response.map((item) => ({
|
||||||
name: item.PARAMDESC,
|
name: item.PARAMDESC,
|
||||||
@ -178,8 +180,8 @@ export class CommonService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getPaymentTypes(_spid: number = 0): Observable<PaymentType[]> {
|
getPaymentTypes(): Observable<PaymentType[]> {
|
||||||
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=008&P_SPID=0`).pipe(
|
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=008&P_SPID=${this.userService.getUserSpid()}`).pipe(
|
||||||
map((response) =>
|
map((response) =>
|
||||||
response.map((item) => ({
|
response.map((item) => ({
|
||||||
name: item.PARAMDESC,
|
name: item.PARAMDESC,
|
||||||
@ -190,8 +192,8 @@ export class CommonService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getFormOfSecurities(spid: number = 0): Observable<FormOfSecurity[]> {
|
getFormOfSecurities(): Observable<FormOfSecurity[]> {
|
||||||
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=016&P_SPID=0`).pipe(
|
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=016&P_SPID=${this.userService.getUserSpid()}`).pipe(
|
||||||
map((response) =>
|
map((response) =>
|
||||||
response.map((item) => ({
|
response.map((item) => ({
|
||||||
name: item.PARAMDESC,
|
name: item.PARAMDESC,
|
||||||
|
|||||||
@ -136,7 +136,8 @@ export class UserService {
|
|||||||
locationid: userDetails.LOCATIONID,
|
locationid: userDetails.LOCATIONID,
|
||||||
urlKey: userDetails.ENCURLKEY,
|
urlKey: userDetails.ENCURLKEY,
|
||||||
logoName: userDetails.LOGONAME,
|
logoName: userDetails.LOGONAME,
|
||||||
themeName: userDetails.THEMENAME
|
themeName: userDetails.THEMENAME,
|
||||||
|
serviceProviderName: userDetails.SPNAME
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -148,7 +148,7 @@
|
|||||||
<mat-icon>chevron_left</mat-icon> Back to application
|
<mat-icon>chevron_left</mat-icon> Back to application
|
||||||
</button>
|
</button>
|
||||||
<button mat-raised-button color="primary" type="submit"
|
<button mat-raised-button color="primary" type="submit"
|
||||||
[disabled]="basicDetailsForm.invalid || !basicDetailsForm.dirty">
|
[disabled]="basicDetailsForm.invalid || !basicDetailsForm.dirty || changeInProgress">
|
||||||
{{ isEditMode ? 'Update' : 'Save' }}
|
{{ isEditMode ? 'Update' : 'Save' }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import { NotificationService } from '../../core/services/common/notification.ser
|
|||||||
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
|
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
|
||||||
import { ZipCodeValidator } from '../../shared/validators/zipcode-validator';
|
import { ZipCodeValidator } from '../../shared/validators/zipcode-validator';
|
||||||
import { CommonService } from '../../core/services/common/common.service';
|
import { CommonService } from '../../core/services/common/common.service';
|
||||||
import { Subject, takeUntil } from 'rxjs';
|
import { finalize, Subject, takeUntil } from 'rxjs';
|
||||||
import { Country } from '../../core/models/country';
|
import { Country } from '../../core/models/country';
|
||||||
import { BasicDetailService } from '../../core/services/holder/basic-detail.service';
|
import { BasicDetailService } from '../../core/services/holder/basic-detail.service';
|
||||||
import { BasicDetail } from '../../core/models/holder/basic-detail';
|
import { BasicDetail } from '../../core/models/holder/basic-detail';
|
||||||
@ -27,7 +27,6 @@ export class BasicDetailComponent implements OnInit, OnDestroy {
|
|||||||
@Input() holderid: number = 0;
|
@Input() holderid: number = 0;
|
||||||
|
|
||||||
@Output() holderIdCreated = new EventEmitter<number>();
|
@Output() holderIdCreated = new EventEmitter<number>();
|
||||||
// @Output() holderName = new EventEmitter<string>();
|
|
||||||
|
|
||||||
basicDetailsForm: FormGroup;
|
basicDetailsForm: FormGroup;
|
||||||
countries: Country[] = [];
|
countries: Country[] = [];
|
||||||
@ -36,6 +35,7 @@ export class BasicDetailComponent implements OnInit, OnDestroy {
|
|||||||
currentApplicationDetails: { headerid: number, applicationName: string } | null = null;
|
currentApplicationDetails: { headerid: number, applicationName: string } | null = null;
|
||||||
|
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
|
changeInProgress = false;
|
||||||
countriesHasStates = ['US', 'CA', 'MX'];
|
countriesHasStates = ['US', 'CA', 'MX'];
|
||||||
|
|
||||||
private destroy$ = new Subject<void>();
|
private destroy$ = new Subject<void>();
|
||||||
@ -60,12 +60,12 @@ export class BasicDetailComponent implements OnInit, OnDestroy {
|
|||||||
holderNumber: ['', [Validators.required, Validators.maxLength(20)]],
|
holderNumber: ['', [Validators.required, Validators.maxLength(20)]],
|
||||||
holderType: ['', [Validators.required, Validators.maxLength(20)]],
|
holderType: ['', [Validators.required, Validators.maxLength(20)]],
|
||||||
uscibMember: [false, [Validators.required]],
|
uscibMember: [false, [Validators.required]],
|
||||||
// govAgency: [false, [Validators.required]],
|
// govAgency: [false, [Validators.required]],
|
||||||
address1: ['', [Validators.required, Validators.maxLength(100)]],
|
address1: ['', [Validators.required, Validators.maxLength(100)]],
|
||||||
address2: ['', Validators.maxLength(100)],
|
address2: ['', Validators.maxLength(100)],
|
||||||
city: ['', [Validators.required, Validators.maxLength(50)]],
|
city: ['', [Validators.required, Validators.maxLength(50)]],
|
||||||
state: ['', Validators.required],
|
state: ['', Validators.required],
|
||||||
country: ['', Validators.required],
|
country: ['US', Validators.required],
|
||||||
zip: ['', [Validators.required, ZipCodeValidator('country')]]
|
zip: ['', [Validators.required, ZipCodeValidator('country')]]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -75,19 +75,21 @@ export class BasicDetailComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
if (this.holderid > 0) {
|
if (this.holderid > 0) {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
this.basicDetailService.getBasicDetailByHolderId(this.holderid).subscribe({
|
this.basicDetailService.getBasicDetailByHolderId(this.holderid).pipe(finalize(() => {
|
||||||
|
this.isLoading = false;
|
||||||
|
})).subscribe({
|
||||||
next: (basicDetail: BasicDetail) => {
|
next: (basicDetail: BasicDetail) => {
|
||||||
this.patchFormData(basicDetail);
|
this.patchFormData(basicDetail);
|
||||||
// this.holderName.emit(basicDetail.holderName);
|
// this.holderName.emit(basicDetail.holderName);
|
||||||
this.isLoading = false;
|
|
||||||
},
|
},
|
||||||
error: (error: any) => {
|
error: (error: any) => {
|
||||||
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load basic details');
|
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load basic details');
|
||||||
this.notificationService.showError(errorMessage);
|
this.notificationService.showError(errorMessage);
|
||||||
this.isLoading = false;
|
|
||||||
console.error('Error loading basic details:', error);
|
console.error('Error loading basic details:', error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
this.loadStates('US'); // Load states for default country
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,12 +120,20 @@ export class BasicDetailComponent implements OnInit, OnDestroy {
|
|||||||
? this.basicDetailService.updateBasicDetails(this.holderid, basicDetailData)
|
? this.basicDetailService.updateBasicDetails(this.holderid, basicDetailData)
|
||||||
: this.basicDetailService.createBasicDetail(basicDetailData);
|
: this.basicDetailService.createBasicDetail(basicDetailData);
|
||||||
|
|
||||||
saveObservable.subscribe({
|
this.changeInProgress = true;
|
||||||
|
|
||||||
|
saveObservable.pipe(finalize(() => {
|
||||||
|
this.changeInProgress = false;
|
||||||
|
})).subscribe({
|
||||||
next: (basicData: any) => {
|
next: (basicData: any) => {
|
||||||
this.notificationService.showSuccess(`Basic details ${this.isEditMode ? 'updated' : 'added'} successfully`);
|
this.notificationService.showSuccess(`Basic details ${this.isEditMode ? 'updated' : 'added'} successfully`);
|
||||||
|
|
||||||
if (!this.isEditMode) {
|
if (!this.isEditMode) {
|
||||||
this.holderIdCreated.emit(basicData.HOLDERID);
|
this.holderIdCreated.emit(basicData.HOLDERID);
|
||||||
|
|
||||||
|
// change to edit mode after creation
|
||||||
|
this.isEditMode = true;
|
||||||
|
this.holderid = basicData.HOLDERID;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (this.isEditMode) {
|
// if (this.isEditMode) {
|
||||||
@ -156,7 +166,7 @@ export class BasicDetailComponent implements OnInit, OnDestroy {
|
|||||||
holderNumber: data.holderNumber,
|
holderNumber: data.holderNumber,
|
||||||
holderType: data.holderType,
|
holderType: data.holderType,
|
||||||
uscibMember: data.uscibMember,
|
uscibMember: data.uscibMember,
|
||||||
// govAgency: data.govAgency,
|
// govAgency: data.govAgency,
|
||||||
address1: data.address1,
|
address1: data.address1,
|
||||||
address2: data.address2,
|
address2: data.address2,
|
||||||
city: data.city,
|
city: data.city,
|
||||||
@ -176,34 +186,29 @@ export class BasicDetailComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
loadLookupData(): void {
|
loadLookupData(): void {
|
||||||
|
|
||||||
this.commonService.getCountries(0)
|
this.commonService.getCountries()
|
||||||
.pipe(takeUntil(this.destroy$))
|
.pipe(takeUntil(this.destroy$))
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: (countries) => {
|
next: (countries) => {
|
||||||
this.countries = countries;
|
this.countries = countries;
|
||||||
this.isLoading = false;
|
|
||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
console.error('Failed to load countries', error);
|
console.error('Failed to load countries', error);
|
||||||
this.isLoading = false;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
loadStates(country: string): void {
|
loadStates(country: string): void {
|
||||||
this.isLoading = true;
|
|
||||||
country = this.countriesHasStates.includes(country) ? country : 'FN';
|
country = this.countriesHasStates.includes(country) ? country : 'FN';
|
||||||
this.commonService.getStates(country, this.holderid)
|
this.commonService.getStates(country)
|
||||||
.pipe(takeUntil(this.destroy$))
|
.pipe(takeUntil(this.destroy$))
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: (states) => {
|
next: (states) => {
|
||||||
this.states = states;
|
this.states = states;
|
||||||
this.updateStateControl('state', country);
|
this.updateStateControl('state', country);
|
||||||
this.isLoading = false;
|
|
||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
console.error('Failed to load states', error);
|
console.error('Failed to load states', error);
|
||||||
this.isLoading = false;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -256,7 +256,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<button mat-raised-button color="primary" type="submit" [disabled]="contactForm.invalid">
|
<button mat-raised-button color="primary" type="submit" [disabled]="contactForm.invalid || changeInProgress">
|
||||||
{{ isEditing ? 'Update' : 'Save' }}
|
{{ isEditing ? 'Update' : 'Save' }}
|
||||||
</button>
|
</button>
|
||||||
<button mat-button type="button" (click)="cancelEdit()">Cancel</button>
|
<button mat-button type="button" (click)="cancelEdit()">Cancel</button>
|
||||||
|
|||||||
@ -16,6 +16,7 @@ import { MatDialog } from '@angular/material/dialog';
|
|||||||
import { ConfirmDialogComponent } from '../../shared/components/confirm-dialog/confirm-dialog.component';
|
import { ConfirmDialogComponent } from '../../shared/components/confirm-dialog/confirm-dialog.component';
|
||||||
import { NavigationService } from '../../core/services/common/navigation.service';
|
import { NavigationService } from '../../core/services/common/navigation.service';
|
||||||
import { StorageService } from '../../core/services/common/storage.service';
|
import { StorageService } from '../../core/services/common/storage.service';
|
||||||
|
import { finalize } from 'rxjs';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-contacts',
|
selector: 'app-contacts',
|
||||||
@ -41,6 +42,7 @@ export class ContactsComponent {
|
|||||||
isEditing = false;
|
isEditing = false;
|
||||||
currentContactId: number | null = null;
|
currentContactId: number | null = null;
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
|
changeInProgress = false;
|
||||||
showForm = false;
|
showForm = false;
|
||||||
showInactiveContacts = false;
|
showInactiveContacts = false;
|
||||||
contacts: Contact[] = [];
|
contacts: Contact[] = [];
|
||||||
@ -67,9 +69,9 @@ export class ContactsComponent {
|
|||||||
lastName: ['', [Validators.required, Validators.maxLength(50)]],
|
lastName: ['', [Validators.required, Validators.maxLength(50)]],
|
||||||
middleInitial: ['', [Validators.maxLength(1)]],
|
middleInitial: ['', [Validators.maxLength(1)]],
|
||||||
title: ['', [Validators.required, Validators.maxLength(100)]],
|
title: ['', [Validators.required, Validators.maxLength(100)]],
|
||||||
phone: ['', [Validators.required, Validators.pattern(/^[0-9]{10,15}$/)]],
|
phone: ['', [Validators.required, Validators.pattern(/^[0-9\-\(\)]{10,15}$/)]],
|
||||||
mobile: ['', [Validators.required, Validators.pattern(/^[0-9]{10,15}$/)]],
|
mobile: ['', [Validators.required, Validators.pattern(/^[0-9\-\(\)]{10,15}$/)]],
|
||||||
fax: ['', [Validators.pattern(/^[0-9]{10,15}$/)]],
|
fax: ['', [Validators.pattern(/^[0-9\-\(\)]{10,15}$/)]],
|
||||||
email: ['', [Validators.required, Validators.email, Validators.maxLength(100)]],
|
email: ['', [Validators.required, Validators.email, Validators.maxLength(100)]],
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -90,16 +92,16 @@ export class ContactsComponent {
|
|||||||
loadContacts(): void {
|
loadContacts(): void {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
|
|
||||||
this.contactService.getContactsById(this.holderid).subscribe({
|
this.contactService.getContactsById(this.holderid).pipe(finalize(() => {
|
||||||
|
this.isLoading = false;
|
||||||
|
})).subscribe({
|
||||||
next: (contacts: Contact[]) => {
|
next: (contacts: Contact[]) => {
|
||||||
this.contacts = contacts;
|
this.contacts = contacts;
|
||||||
this.renderContacts();
|
this.renderContacts();
|
||||||
this.isLoading = false;
|
|
||||||
},
|
},
|
||||||
error: (error: any) => {
|
error: (error: any) => {
|
||||||
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load contacts');
|
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to load contacts');
|
||||||
this.notificationService.showError(errorMessage);
|
this.notificationService.showError(errorMessage);
|
||||||
this.isLoading = false;
|
|
||||||
console.error('Error loading contacts:', error);
|
console.error('Error loading contacts:', error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -146,7 +148,11 @@ export class ContactsComponent {
|
|||||||
? this.contactService.updateContact(this.currentContactId!, contactData)
|
? this.contactService.updateContact(this.currentContactId!, contactData)
|
||||||
: this.contactService.createContact(this.holderid, contactData);
|
: this.contactService.createContact(this.holderid, contactData);
|
||||||
|
|
||||||
saveObservable.subscribe({
|
this.changeInProgress = true;
|
||||||
|
|
||||||
|
saveObservable.pipe(finalize(() => {
|
||||||
|
this.changeInProgress = false;
|
||||||
|
})).subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
this.notificationService.showSuccess(`Contact ${this.isEditing ? 'updated' : 'added'} successfully`);
|
this.notificationService.showSuccess(`Contact ${this.isEditing ? 'updated' : 'added'} successfully`);
|
||||||
this.loadContacts();
|
this.loadContacts();
|
||||||
|
|||||||
@ -117,7 +117,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<button mat-raised-button color="primary" type="submit" (click)="saveHolderSelection()">
|
<button mat-raised-button color="primary" type="submit" [disabled]="changeInProgress" (click)="saveHolderSelection()">
|
||||||
{{ 'Save' }}
|
{{ 'Save' }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { Component, EventEmitter, inject, Input, Output, ViewChild } from '@angular/core';
|
import { Component, EventEmitter, inject, Input, Output, SimpleChanges, ViewChild } from '@angular/core';
|
||||||
import { AngularMaterialModule } from '../../shared/module/angular-material.module';
|
import { AngularMaterialModule } from '../../shared/module/angular-material.module';
|
||||||
import { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms';
|
import { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
@ -18,6 +18,7 @@ import { HolderFilter } from '../../core/models/holder/holder-filter';
|
|||||||
import { ConfirmDialogComponent } from '../../shared/components/confirm-dialog/confirm-dialog.component';
|
import { ConfirmDialogComponent } from '../../shared/components/confirm-dialog/confirm-dialog.component';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { StorageService } from '../../core/services/common/storage.service';
|
import { StorageService } from '../../core/services/common/storage.service';
|
||||||
|
import { finalize } from 'rxjs';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-holder-search',
|
selector: 'app-holder-search',
|
||||||
@ -27,11 +28,16 @@ import { StorageService } from '../../core/services/common/storage.service';
|
|||||||
providers: [{ provide: MatPaginatorIntl, useClass: CustomPaginator }],
|
providers: [{ provide: MatPaginatorIntl, useClass: CustomPaginator }],
|
||||||
})
|
})
|
||||||
export class SearchHolderComponent {
|
export class SearchHolderComponent {
|
||||||
|
private _paginator!: MatPaginator;
|
||||||
|
|
||||||
@ViewChild(MatPaginator, { static: false })
|
@ViewChild(MatPaginator, { static: false })
|
||||||
set paginator(value: MatPaginator) {
|
set paginator(value: MatPaginator) {
|
||||||
|
this._paginator = value;
|
||||||
this.dataSource.paginator = value;
|
this.dataSource.paginator = value;
|
||||||
}
|
}
|
||||||
|
get paginator(): MatPaginator {
|
||||||
|
return this._paginator;
|
||||||
|
}
|
||||||
|
|
||||||
@ViewChild(MatSort, { static: false })
|
@ViewChild(MatSort, { static: false })
|
||||||
set sort(value: MatSort) {
|
set sort(value: MatSort) {
|
||||||
@ -47,6 +53,7 @@ export class SearchHolderComponent {
|
|||||||
showInactiveHolders: boolean = false;
|
showInactiveHolders: boolean = false;
|
||||||
holders: BasicDetail[] = []
|
holders: BasicDetail[] = []
|
||||||
isLoading: boolean = false;
|
isLoading: boolean = false;
|
||||||
|
changeInProgress: boolean = false;
|
||||||
userPreferences: UserPreferences;
|
userPreferences: UserPreferences;
|
||||||
searchForm: FormGroup;
|
searchForm: FormGroup;
|
||||||
|
|
||||||
@ -62,7 +69,8 @@ export class SearchHolderComponent {
|
|||||||
dataSource = new MatTableDataSource<any>([]);
|
dataSource = new MatTableDataSource<any>([]);
|
||||||
|
|
||||||
ngAfterViewInit() {
|
ngAfterViewInit() {
|
||||||
this.dataSource.paginator = this.paginator;
|
// This is different from other pages to show the item selected in the table.
|
||||||
|
//this.dataSource.paginator = this.paginator;
|
||||||
this.dataSource.sort = this.sort;
|
this.dataSource.sort = this.sort;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,14 +93,25 @@ export class SearchHolderComponent {
|
|||||||
this.searchHolders();
|
this.searchHolders();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnChanges(changes: SimpleChanges): void {
|
||||||
|
if (changes['selectedHolderId'] && this.paginator) {
|
||||||
|
if (this.selectedHolderId && this.dataSource.data.length) {
|
||||||
|
this.goToItemPage(this.selectedHolderId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onSearch(): void {
|
onSearch(): void {
|
||||||
this.searchHolders();
|
this.searchHolders();
|
||||||
}
|
}
|
||||||
|
|
||||||
saveHolderSelection(): void {
|
saveHolderSelection(): void {
|
||||||
|
this.changeInProgress = true;
|
||||||
const saveObservable = this.carnetHolderService.saveApplicationHolder(this.headerid, this.selectedHolderId ? Number(this.selectedHolderId) : 0);
|
const saveObservable = this.carnetHolderService.saveApplicationHolder(this.headerid, this.selectedHolderId ? Number(this.selectedHolderId) : 0);
|
||||||
|
|
||||||
saveObservable.subscribe({
|
saveObservable.pipe(finalize(() => {
|
||||||
|
this.changeInProgress = false;
|
||||||
|
})).subscribe({
|
||||||
next: (basicData: any) => {
|
next: (basicData: any) => {
|
||||||
this.notificationService.showSuccess(`Holder updated successfully`);
|
this.notificationService.showSuccess(`Holder updated successfully`);
|
||||||
this.holderSelectionCompleted.emit(true);
|
this.holderSelectionCompleted.emit(true);
|
||||||
@ -114,16 +133,16 @@ export class SearchHolderComponent {
|
|||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
const filterData: HolderFilter = this.searchForm.value;
|
const filterData: HolderFilter = this.searchForm.value;
|
||||||
|
|
||||||
this.holderService.getHolders(filterData).subscribe({
|
this.holderService.getHolders(filterData).pipe(finalize(() => {
|
||||||
|
this.isLoading = false;
|
||||||
|
})).subscribe({
|
||||||
next: (holders: BasicDetail[]) => {
|
next: (holders: BasicDetail[]) => {
|
||||||
this.dataSource.data = this.holders = holders;
|
this.dataSource.data = this.holders = holders;
|
||||||
this.renderHolders()
|
this.renderHolders()
|
||||||
this.isLoading = false;
|
|
||||||
},
|
},
|
||||||
error: (error: any) => {
|
error: (error: any) => {
|
||||||
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to search holders');
|
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to search holders');
|
||||||
this.notificationService.showError(errorMessage);
|
this.notificationService.showError(errorMessage);
|
||||||
this.isLoading = false;
|
|
||||||
console.error('Error loading holders:', error);
|
console.error('Error loading holders:', error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -222,8 +241,25 @@ export class SearchHolderComponent {
|
|||||||
|
|
||||||
getAddressLabel(holder: BasicDetail): string {
|
getAddressLabel(holder: BasicDetail): string {
|
||||||
|
|
||||||
return `${holder.address1}, ${holder.address2}
|
const parts = [
|
||||||
${holder.city}, ${holder.state}, ${holder.zip},
|
holder.address1,
|
||||||
${holder.country}`;
|
holder.address2,
|
||||||
|
holder.city,
|
||||||
|
holder.state,
|
||||||
|
holder.zip,
|
||||||
|
holder.country
|
||||||
|
];
|
||||||
|
|
||||||
|
// Filter out any empty, null, or undefined parts and then join them.
|
||||||
|
return parts.filter(part => part).join(', ');
|
||||||
|
}
|
||||||
|
|
||||||
|
goToItemPage(holderid: number): void {
|
||||||
|
const itemIndex = this.dataSource.data.findIndex(dataItem => dataItem.holderid === holderid);
|
||||||
|
if (itemIndex > -1 && this.paginator) {
|
||||||
|
const targetPageIndex = Math.floor(itemIndex / this.paginator.pageSize);
|
||||||
|
this.paginator.pageIndex = targetPageIndex;
|
||||||
|
this.dataSource.paginator = this.paginator;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user