auth integration updates
This commit is contained in:
parent
38021b8979
commit
b44f482449
@ -82,7 +82,8 @@
|
|||||||
"buildTarget": "service-provider-app:build:production"
|
"buildTarget": "service-provider-app:build:production"
|
||||||
},
|
},
|
||||||
"development": {
|
"development": {
|
||||||
"buildTarget": "service-provider-app:build:development"
|
"buildTarget": "service-provider-app:build:development",
|
||||||
|
"port": 5173
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"defaultConfiguration": "development"
|
"defaultConfiguration": "development"
|
||||||
|
|||||||
@ -4,13 +4,16 @@ import { provideRouter } from '@angular/router';
|
|||||||
import { routes } from './app.routes';
|
import { routes } from './app.routes';
|
||||||
import { provideClientHydration, withEventReplay } from '@angular/platform-browser';
|
import { provideClientHydration, withEventReplay } from '@angular/platform-browser';
|
||||||
import { provideCharts, withDefaultRegisterables } from 'ng2-charts';
|
import { provideCharts, withDefaultRegisterables } from 'ng2-charts';
|
||||||
import { provideHttpClient } from '@angular/common/http';
|
import { HTTP_INTERCEPTORS, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
|
||||||
|
import { AuthInterceptor } from './core/interceptors/auth.interceptor';
|
||||||
|
|
||||||
export const appConfig: ApplicationConfig = {
|
export const appConfig: ApplicationConfig = {
|
||||||
providers: [
|
providers: [
|
||||||
provideZoneChangeDetection({ eventCoalescing: true }),
|
provideZoneChangeDetection({ eventCoalescing: true }),
|
||||||
provideRouter(routes),
|
provideRouter(routes),
|
||||||
provideClientHydration(withEventReplay()),
|
provideClientHydration(withEventReplay()),
|
||||||
provideHttpClient(),
|
provideHttpClient(withInterceptorsFromDi()),
|
||||||
provideCharts(withDefaultRegisterables())]
|
provideCharts(withDefaultRegisterables()),
|
||||||
|
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
|
||||||
|
]
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,12 +1,10 @@
|
|||||||
import { Component, effect, OnInit } from '@angular/core';
|
import { Component, effect, OnInit } from '@angular/core';
|
||||||
import { UserService } from '../../core/services/common/user.service';
|
import { UserService } from '../../core/services/common/user.service';
|
||||||
import { Router } from '@angular/router';
|
|
||||||
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 { NavigationService } from '../../core/services/common/navigation.service';
|
import { NavigationService } from '../../core/services/common/navigation.service';
|
||||||
import { User } from '../../core/models/user';
|
import { User } from '../../core/models/user';
|
||||||
import { ThemeService } from '../../core/services/theme.service';
|
import { AuthService } from '../../core/services/common/auth.service';
|
||||||
import { StorageService } from '../../core/services/common/storage.service';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-secured-header',
|
selector: 'app-secured-header',
|
||||||
@ -22,10 +20,8 @@ export class SecuredHeaderComponent implements OnInit {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private userService: UserService,
|
private userService: UserService,
|
||||||
private router: Router,
|
|
||||||
private navigationService: NavigationService,
|
private navigationService: NavigationService,
|
||||||
private themeService: ThemeService,
|
private authService: AuthService
|
||||||
private storageService: StorageService
|
|
||||||
) {
|
) {
|
||||||
effect(() => {
|
effect(() => {
|
||||||
this.userDetails = this.userService.userDetailsSignal();
|
this.userDetails = this.userService.userDetailsSignal();
|
||||||
@ -44,9 +40,6 @@ export class SecuredHeaderComponent implements OnInit {
|
|||||||
setApplicationDetails() {
|
setApplicationDetails() {
|
||||||
if (this.userDetails?.userDetails) {
|
if (this.userDetails?.userDetails) {
|
||||||
this.logoUrl = `images/logos/${this.userDetails?.userDetails?.logoName}`;
|
this.logoUrl = `images/logos/${this.userDetails?.userDetails?.logoName}`;
|
||||||
this.themeService.setTheme(this.userDetails?.userDetails?.themeName);
|
|
||||||
} else {
|
|
||||||
this.themeService.setTheme('default');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,15 +48,11 @@ export class SecuredHeaderComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
logout(): void {
|
logout(): void {
|
||||||
this.userService.clearUser();
|
this.authService.logout();
|
||||||
this.storageService.clear();
|
|
||||||
this.router.navigate(['/login']);
|
|
||||||
this.showProfileMenu = false;
|
this.showProfileMenu = false;
|
||||||
this.themeService.setTheme('default');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
navigateTo(route: string): void {
|
navigateTo(route: string): void {
|
||||||
|
|
||||||
this.navigationService.navigate([route]);
|
this.navigationService.navigate([route]);
|
||||||
this.showProfileMenu = false;
|
this.showProfileMenu = false;
|
||||||
}
|
}
|
||||||
|
|||||||
111
src/app/core/interceptors/auth.interceptor.ts
Normal file
111
src/app/core/interceptors/auth.interceptor.ts
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
// auth.interceptor.ts
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HttpErrorResponse } from '@angular/common/http';
|
||||||
|
import { Observable, throwError, BehaviorSubject } from 'rxjs';
|
||||||
|
import { catchError, filter, switchMap, take } from 'rxjs/operators';
|
||||||
|
import { AuthService } from '../services/common/auth.service';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class AuthInterceptor implements HttpInterceptor {
|
||||||
|
|
||||||
|
private isRefreshing = false;
|
||||||
|
private refreshTokenSubject: BehaviorSubject<any> = new BehaviorSubject<any>(null);
|
||||||
|
|
||||||
|
private requestQueue: { request: HttpRequest<any>, next: HttpHandler }[] = [];
|
||||||
|
|
||||||
|
constructor(private authService: AuthService) { }
|
||||||
|
|
||||||
|
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
|
||||||
|
|
||||||
|
// Add withCredentials to all requests
|
||||||
|
request = request.clone({
|
||||||
|
withCredentials: true
|
||||||
|
});
|
||||||
|
|
||||||
|
return next.handle(request).pipe(
|
||||||
|
catchError((error: HttpErrorResponse) => {
|
||||||
|
if (error.status === 401) {
|
||||||
|
// Handle 401 Unauthorized responses
|
||||||
|
if (error.url?.includes('refresh-tokens')) {
|
||||||
|
return throwError(() => error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.handle401Error(request, next);
|
||||||
|
} else {
|
||||||
|
return throwError(() => error);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private handle401Error(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
|
||||||
|
if (!this.isRefreshing) {
|
||||||
|
this.isRefreshing = true;
|
||||||
|
this.refreshTokenSubject.next(null);
|
||||||
|
|
||||||
|
return this.authService.refreshToken().pipe(
|
||||||
|
switchMap((token: any) => {
|
||||||
|
this.isRefreshing = false;
|
||||||
|
this.refreshTokenSubject.next(token);
|
||||||
|
|
||||||
|
// Retry all queued requests with new token
|
||||||
|
this.retryQueuedRequests();
|
||||||
|
|
||||||
|
// Retry the original request
|
||||||
|
request = request.clone({
|
||||||
|
withCredentials: true
|
||||||
|
});
|
||||||
|
|
||||||
|
return next.handle(request);
|
||||||
|
}),
|
||||||
|
catchError((err) => {
|
||||||
|
this.isRefreshing = false;
|
||||||
|
this.authService.logout();
|
||||||
|
return throwError(() => err);
|
||||||
|
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// If token refresh is already in progress, add to queue
|
||||||
|
return this.addRequestToQueue(request, next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private addRequestToQueue(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
|
||||||
|
return new Observable<HttpEvent<any>>(observer => {
|
||||||
|
const subscription = this.refreshTokenSubject.pipe(
|
||||||
|
filter(token => token !== null),
|
||||||
|
take(1)
|
||||||
|
).subscribe(token => {
|
||||||
|
// Remove from queue
|
||||||
|
const index = this.requestQueue.findIndex(item => item.request === request);
|
||||||
|
if (index > -1) {
|
||||||
|
this.requestQueue.splice(index, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retry request with new token
|
||||||
|
next.handle(request).subscribe({
|
||||||
|
next: event => observer.next(event),
|
||||||
|
error: err => observer.error(err),
|
||||||
|
complete: () => observer.complete()
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add to queue
|
||||||
|
this.requestQueue.push({ request, next });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private retryQueuedRequests(): void {
|
||||||
|
// Process all queued requests
|
||||||
|
while (this.requestQueue.length > 0) {
|
||||||
|
let { request, next } = this.requestQueue.shift()!;
|
||||||
|
|
||||||
|
request = request.clone({
|
||||||
|
withCredentials: true
|
||||||
|
});
|
||||||
|
|
||||||
|
next.handle(request).subscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,7 +1,13 @@
|
|||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable, tap } from 'rxjs';
|
||||||
import { environment } from '../../../../environments/environment';
|
import { environment } from '../../../../environments/environment';
|
||||||
|
import { UserService } from './user.service';
|
||||||
|
import { StorageService } from './storage.service';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
import { ThemeService } from '../theme.service';
|
||||||
|
import { NotificationService } from './notification.service';
|
||||||
|
import { ApiErrorHandlerService } from './api-error-handler.service';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
@ -9,9 +15,38 @@ import { environment } from '../../../../environments/environment';
|
|||||||
export class AuthService {
|
export class AuthService {
|
||||||
private apiUrl = environment.apiUrl;
|
private apiUrl = environment.apiUrl;
|
||||||
|
|
||||||
constructor(private http: HttpClient) { }
|
constructor(private http: HttpClient,
|
||||||
|
private userService: UserService,
|
||||||
|
private storageService: StorageService,
|
||||||
|
private router: Router,
|
||||||
|
private themeService: ThemeService,
|
||||||
|
private notificationService: NotificationService,
|
||||||
|
private errorHandler: ApiErrorHandlerService
|
||||||
|
) { }
|
||||||
|
|
||||||
login(username: string, password: string): Observable<any> {
|
login(username: string, password: string): Observable<any> {
|
||||||
return this.http.post(`${this.apiUrl}/login`, { p_emailaddr: username, p_password: password });
|
return this.http.post(`${this.apiUrl}/login`, { p_emailaddr: username, p_password: password });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
refreshToken(): Observable<any> {
|
||||||
|
return this.http.get(`${this.apiUrl}/refresh-tokens`, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
logout(): void {
|
||||||
|
if (this.userService.isLoggedIn()) {
|
||||||
|
this.http.post(`${this.apiUrl}/logout`, {}).subscribe({
|
||||||
|
next: (response) => {
|
||||||
|
this.userService.clearUser();
|
||||||
|
this.storageService.clear();
|
||||||
|
this.router.navigate(['/login']);
|
||||||
|
this.themeService.setTheme('default');;
|
||||||
|
}
|
||||||
|
, error: (error) => {
|
||||||
|
let errorMessage = this.errorHandler.handleApiError(error, `Logout failed`);
|
||||||
|
this.notificationService.showError(errorMessage);
|
||||||
|
console.error('Logout failed:', error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,7 +19,7 @@ export class UserService {
|
|||||||
private readonly USER_EMAIL_KEY = 'CurrentUserEmail';
|
private readonly USER_EMAIL_KEY = 'CurrentUserEmail';
|
||||||
private readonly USER_DETAILS_KEY = 'CurrentUserData';
|
private readonly USER_DETAILS_KEY = 'CurrentUserData';
|
||||||
|
|
||||||
private userLoggedInSubject = new BehaviorSubject<boolean>(true);
|
private userLoggedInSubject = new BehaviorSubject<boolean>(false);
|
||||||
|
|
||||||
constructor(private http: HttpClient, private storageService: StorageService) { }
|
constructor(private http: HttpClient, private storageService: StorageService) { }
|
||||||
|
|
||||||
@ -90,6 +90,7 @@ export class UserService {
|
|||||||
}
|
}
|
||||||
return this.spid;
|
return this.spid;
|
||||||
}
|
}
|
||||||
|
|
||||||
private mapToUser(data: any): User {
|
private mapToUser(data: any): User {
|
||||||
return {
|
return {
|
||||||
roles: data.roleDetails || null,
|
roles: data.roleDetails || null,
|
||||||
|
|||||||
@ -1,10 +1,5 @@
|
|||||||
<div class="login-container">
|
<div class="login-container">
|
||||||
<div class="login-card">
|
<div class="login-card">
|
||||||
<!-- <div class="logo-container">
|
|
||||||
<img src="images/logo.jpeg" alt="USCIB Logo" class="logo">
|
|
||||||
</div> -->
|
|
||||||
<!--
|
|
||||||
<h2 class="welcome-title">Welcome to USCIB Carnet Portal!</h2> -->
|
|
||||||
<h3 class="subtitle">ATA Carnet: Your Passport for Duty-Free Global Trade</h3>
|
<h3 class="subtitle">ATA Carnet: Your Passport for Duty-Free Global Trade</h3>
|
||||||
|
|
||||||
<form [formGroup]="loginForm" (ngSubmit)="onSubmit()" class="login-form">
|
<form [formGroup]="loginForm" (ngSubmit)="onSubmit()" class="login-form">
|
||||||
|
|||||||
@ -13,21 +13,6 @@
|
|||||||
background-color: white;
|
background-color: white;
|
||||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||||
|
|
||||||
.logo-container {
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
max-width: 120px;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.welcome-title {
|
|
||||||
text-align: center;
|
|
||||||
color: #597b7c;
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.subtitle {
|
.subtitle {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #666;
|
color: #666;
|
||||||
|
|||||||
@ -58,11 +58,11 @@ export class LoginComponent {
|
|||||||
|
|
||||||
this.authService.login(username, password).subscribe({
|
this.authService.login(username, password).subscribe({
|
||||||
next: (response) => {
|
next: (response) => {
|
||||||
if (response?.msg) {
|
if (response?.message) {
|
||||||
this.userService.setUser(username);
|
this.userService.setUser(response?.email);
|
||||||
this.setUserData();
|
this.setUserData();
|
||||||
} else {
|
} else {
|
||||||
this.errorMessage = response?.error ?? response?.msg;
|
this.errorMessage = response?.error ?? response?.message;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
@ -80,10 +80,12 @@ export class LoginComponent {
|
|||||||
next: (data: User) => {
|
next: (data: User) => {
|
||||||
if (data?.userDetails) {
|
if (data?.userDetails) {
|
||||||
this.navigationService.setCurrentAppId(data.userDetails.urlKey);
|
this.navigationService.setCurrentAppId(data.userDetails.urlKey);
|
||||||
|
this.themeService.setTheme(data.userDetails.themeName);
|
||||||
this.navigationService.navigate(['home']);
|
this.navigationService.navigate(['home']);
|
||||||
} else {
|
} else {
|
||||||
this.errorMessage = "User doesn't have permissions.";
|
this.errorMessage = "User doesn't have permissions.";
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
|
this.themeService.setTheme('default');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error: (error: any) => {
|
error: (error: any) => {
|
||||||
|
|||||||
@ -80,7 +80,7 @@
|
|||||||
</button>
|
</button>
|
||||||
<button mat-icon-button color="warn" *ngIf="contact.isInactive" (click)="
|
<button mat-icon-button color="warn" *ngIf="contact.isInactive" (click)="
|
||||||
reactivateContact(contact.clientContactId)" [hidden]="!contact.isInactive" matTooltip="Reactivate">
|
reactivateContact(contact.clientContactId)" [hidden]="!contact.isInactive" matTooltip="Reactivate">
|
||||||
<mat-icon>how_to_reg</mat-icon>
|
<mat-icon>loupe</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<!-- <button mat-icon-button (click)="setDefaultContact(contact.contactId)"
|
<!-- <button mat-icon-button (click)="setDefaultContact(contact.contactId)"
|
||||||
[color]="contact.defaultContact ? 'primary' : ''" matTooltip="Set as default">
|
[color]="contact.defaultContact ? 'primary' : ''" matTooltip="Set as default">
|
||||||
|
|||||||
@ -20,8 +20,7 @@
|
|||||||
<!-- Address1 Column -->
|
<!-- Address1 Column -->
|
||||||
<ng-container matColumnDef="address">
|
<ng-container matColumnDef="address">
|
||||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>Address</th>
|
<th mat-header-cell *matHeaderCellDef mat-sort-header>Address</th>
|
||||||
<td mat-cell *matCellDef="let location">{{ getAddressLabel(location.address1, location.address2,
|
<td mat-cell *matCellDef="let location">{{ getAddressLabel(location.address1, location.address2) }}</td>
|
||||||
location.zip) }}</td>
|
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<!-- City Column -->
|
<!-- City Column -->
|
||||||
@ -39,7 +38,7 @@
|
|||||||
<!-- Country Column -->
|
<!-- Country Column -->
|
||||||
<ng-container matColumnDef="country">
|
<ng-container matColumnDef="country">
|
||||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>Country</th>
|
<th mat-header-cell *matHeaderCellDef mat-sort-header>Country</th>
|
||||||
<td mat-cell *matCellDef="let location">{{ location.country }}</td>
|
<td mat-cell *matCellDef="let location">{{ getCountryLabel(location.country) }}</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<!-- Actions Column -->
|
<!-- Actions Column -->
|
||||||
|
|||||||
@ -242,14 +242,11 @@ export class LocationComponent {
|
|||||||
// });
|
// });
|
||||||
// }
|
// }
|
||||||
|
|
||||||
getAddressLabel(address1: string, address2?: string, zip?: string): string {
|
getAddressLabel(address1: string, address2?: string): string {
|
||||||
let addressLabel = address1;
|
let addressLabel = address1;
|
||||||
if (address2) {
|
if (address2) {
|
||||||
addressLabel += `, ${address2}`;
|
addressLabel += `, ${address2}`;
|
||||||
}
|
}
|
||||||
if (zip) {
|
|
||||||
addressLabel += `, ${zip}`;
|
|
||||||
}
|
|
||||||
return addressLabel;
|
return addressLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -97,7 +97,7 @@
|
|||||||
<!-- Carnet Issuing region Column -->
|
<!-- Carnet Issuing region Column -->
|
||||||
<ng-container matColumnDef="carnetIssuingRegion">
|
<ng-container matColumnDef="carnetIssuingRegion">
|
||||||
<th mat-header-cell *matHeaderCellDef mat-sort-header>Carnet Issuing region </th>
|
<th mat-header-cell *matHeaderCellDef mat-sort-header>Carnet Issuing region </th>
|
||||||
<td mat-cell *matCellDef="let client">{{getRegionLabel(client.carnetIssuingRegion)}}</td>
|
<td mat-cell *matCellDef="let client">{{client.carnetIssuingRegion}}</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<!-- Revenue Location Column -->
|
<!-- Revenue Location Column -->
|
||||||
|
|||||||
@ -41,8 +41,6 @@ export class ManagePreparerComponent implements OnInit, OnDestroy, AfterViewInit
|
|||||||
searchForm: FormGroup;
|
searchForm: FormGroup;
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
userPreferences: UserPreferences;
|
userPreferences: UserPreferences;
|
||||||
countries: Country[] = [];
|
|
||||||
regions: Region[] = [];
|
|
||||||
|
|
||||||
displayedColumns: string[] = ['name', 'address', 'city', 'state', 'country', 'carnetIssuingRegion', 'revenueLocation', 'actions'];
|
displayedColumns: string[] = ['name', 'address', 'city', 'state', 'country', 'carnetIssuingRegion', 'revenueLocation', 'actions'];
|
||||||
dataSource = new MatTableDataSource<any>([]);
|
dataSource = new MatTableDataSource<any>([]);
|
||||||
@ -63,8 +61,6 @@ export class ManagePreparerComponent implements OnInit, OnDestroy, AfterViewInit
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.loadCountries();
|
|
||||||
this.loadRegions();
|
|
||||||
this.searchPreparers();
|
this.searchPreparers();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,35 +129,6 @@ export class ManagePreparerComponent implements OnInit, OnDestroy, AfterViewInit
|
|||||||
this.navigationService.navigate(['preparer', clientid]);
|
this.navigationService.navigate(['preparer', clientid]);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadRegions(): void {
|
|
||||||
this.commonService.getRegions()
|
|
||||||
.pipe(takeUntil(this.destroy$))
|
|
||||||
.subscribe({
|
|
||||||
next: (regions) => {
|
|
||||||
this.regions = regions;
|
|
||||||
this.isLoading = false;
|
|
||||||
},
|
|
||||||
error: (error) => {
|
|
||||||
console.error('Failed to load regions', error);
|
|
||||||
this.isLoading = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
loadCountries(): void {
|
|
||||||
this.commonService.getCountries(0)
|
|
||||||
.pipe(takeUntil(this.destroy$))
|
|
||||||
.subscribe({
|
|
||||||
next: (countries) => {
|
|
||||||
this.countries = countries;
|
|
||||||
},
|
|
||||||
error: (error) => {
|
|
||||||
console.error('Failed to load countries', error);
|
|
||||||
this.isLoading = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
getAddressLabel(address1: string, address2?: string): string {
|
getAddressLabel(address1: string, address2?: string): string {
|
||||||
let addressLabel = address1;
|
let addressLabel = address1;
|
||||||
if (address2) {
|
if (address2) {
|
||||||
@ -169,14 +136,4 @@ export class ManagePreparerComponent implements OnInit, OnDestroy, AfterViewInit
|
|||||||
}
|
}
|
||||||
return addressLabel;
|
return addressLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
getRegionLabel(value: string): string {
|
|
||||||
const region = this.regions.find(r => r.region === value);
|
|
||||||
return region ? region.regionname : value;
|
|
||||||
}
|
|
||||||
|
|
||||||
getCountryLabel(value: string): string {
|
|
||||||
const country = this.countries.find(c => c.value === value);
|
|
||||||
return country ? country.name : value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -2,7 +2,7 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>ServiceProviderApp</title>
|
<title>Service Provider</title>
|
||||||
<base href="/">
|
<base href="/">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user