manage fee and region updates

This commit is contained in:
Cyril Joseph 2025-11-08 11:19:32 -04:00
parent b928978044
commit 8163b02f34
54 changed files with 474 additions and 115 deletions

View File

@ -3,7 +3,7 @@ import { environment } from '../../../../environments/environment';
import { HttpClient } from '@angular/common/http';
import { map, Observable } from 'rxjs';
import { UserService } from '../common/user.service';
import { BasicFee } from '../../models/service-provider/basic-fee';
import { BasicFee } from '../../models/fees/basic-fee';
import { CommonService } from '../common/common.service';
@Injectable({

View File

@ -4,7 +4,7 @@ import { map, Observable } from 'rxjs';
import { environment } from '../../../../environments/environment';
import { CommonService } from '../common/common.service';
import { UserService } from '../common/user.service';
import { CargoRate } from '../../models/service-provider/cargo-rate';
import { CargoRate } from '../../models/fees/cargo-rate';
@Injectable({
providedIn: 'root'

View File

@ -2,7 +2,7 @@ import { inject, Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { map, Observable } from 'rxjs';
import { environment } from '../../../../environments/environment';
import { CarnetFee } from '../../models/service-provider/carnet-fee';
import { CarnetFee } from '../../models/fees/carnet-fee';
import { CommonService } from '../common/common.service';
import { UserService } from '../common/user.service';

View File

@ -2,7 +2,7 @@ import { inject, Injectable } from '@angular/core';
import { map, Observable } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import { environment } from '../../../../environments/environment';
import { ContinuationSheetFee } from '../../models/service-provider/continuation-sheet-fee';
import { ContinuationSheetFee } from '../../models/fees/continuation-sheet-fee';
import { CommonService } from '../common/common.service';
import { UserService } from '../common/user.service';

View File

@ -2,7 +2,7 @@ import { inject, Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { map, Observable } from 'rxjs';
import { environment } from '../../../../environments/environment';
import { CounterfoilFee } from '../../models/service-provider/counterfoil-fee';
import { CounterfoilFee } from '../../models/fees/counterfoil-fee';
import { CommonService } from '../common/common.service';
import { UserService } from '../common/user.service';

View File

@ -2,7 +2,7 @@ import { inject, Injectable } from '@angular/core';
import { map, Observable } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import { environment } from '../../../../environments/environment';
import { ExpeditedFee } from '../../models/service-provider/expedited-fee';
import { ExpeditedFee } from '../../models/fees/expedited-fee';
import { CommonService } from '../common/common.service';
import { UserService } from '../common/user.service';

View File

@ -2,7 +2,7 @@ import { HttpClient } from '@angular/common/http';
import { inject, Injectable } from '@angular/core';
import { map, Observable } from 'rxjs';
import { environment } from '../../../../environments/environment';
import { SecurityDeposit } from '../../models/service-provider/security-deposit';
import { SecurityDeposit } from '../../models/fees/security-deposit';
import { CommonService } from '../common/common.service';
import { UserService } from '../common/user.service';

View File

@ -2,16 +2,16 @@ import { Component, EventEmitter, inject, Input, Output, ViewChild } from '@angu
import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { BasicFee } from '../../core/models/service-provider/basic-fee';
import { BasicFee } from '../../core/models/fees/basic-fee';
import { AngularMaterialModule } from '../../shared/module/angular-material.module';
import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { CustomPaginator } from '../../shared/custom-paginator';
import { finalize, forkJoin } from 'rxjs';
import { concat, finalize } from 'rxjs';
import { UserPreferences } from '../../core/models/user-preference';
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
import { NotificationService } from '../../core/services/common/notification.service';
import { BasicFeeService } from '../../core/services/service-provider/basic-fee.service';
import { BasicFeeService } from '../../core/services/fees/basic-fee.service';
@Component({
selector: 'app-basic-fee',
@ -26,10 +26,7 @@ export class BasicFeeComponent {
this.dataSource.paginator = value;
}
@ViewChild(MatSort, { static: false })
set sort(value: MatSort) {
this.dataSource.sort = value;
}
@ViewChild(MatSort) sort!: MatSort;
displayedColumns: string[] = ['startCarnetValue', 'endCarnetValue', 'fees', 'effectiveDate', 'actions'];
dataSource = new MatTableDataSource<BasicFee>();
@ -128,11 +125,15 @@ export class BasicFeeComponent {
this.changeInProgress = true;
// Execute all creations in parallel and wait for all to complete
forkJoin(creationObservables).pipe(finalize(() => {
this.changeInProgress = false;
})).subscribe({
// Execute all creations in sequence
concat(...creationObservables).pipe(
finalize(() => {
this.changeInProgress = false;
})
).subscribe({
next: () => {
},
complete: () => {
this.loadBasicFees(); // Refresh the list after all creations are done
},
error: (error) => {

View File

@ -10,8 +10,8 @@ import { UserPreferences } from '../../core/models/user-preference';
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
import { NotificationService } from '../../core/services/common/notification.service';
import { finalize } from 'rxjs';
import { CargoRate } from '../../core/models/service-provider/cargo-rate';
import { CargoRateService } from '../../core/services/service-provider/cargo-rate.service';
import { CargoRate } from '../../core/models/fees/cargo-rate';
import { CargoRateService } from '../../core/services/fees/cargo-rate.service';
@Component({
selector: 'app-cargo-rate',
@ -25,11 +25,8 @@ export class CargoRateComponent implements OnInit {
set paginator(value: MatPaginator) {
this.dataSource.paginator = value;
}
@ViewChild(MatSort, { static: false })
set sort(value: MatSort) {
this.dataSource.sort = value;
}
@ViewChild(MatSort) sort!: MatSort;
displayedColumns: string[] = ['carnetType', 'startSets', 'endSets', 'rate', 'effectiveDate', 'actions'];
dataSource = new MatTableDataSource<any>();
@ -101,7 +98,6 @@ export class CargoRateComponent implements OnInit {
}
loadCargoRates(): void {
if (!this.spid) return;
this.isLoading = true;
this.cargoRateService.getCargoRates(this.spid).pipe(finalize(() => {

View File

@ -80,9 +80,7 @@
Fee type is required
</mat-error>
</mat-form-field>
</div>
<div class="form-row">
<mat-form-field appearance="outline">
<mat-label>Commission Rate</mat-label>
<input matInput type="number" formControlName="commissionRate">

View File

@ -7,13 +7,13 @@ import { MatTableDataSource } from '@angular/material/table';
import { AngularMaterialModule } from '../../shared/module/angular-material.module';
import { CommonModule } from '@angular/common';
import { CustomPaginator } from '../../shared/custom-paginator';
import { CarnetFee } from '../../core/models/service-provider/carnet-fee';
import { CarnetFee } from '../../core/models/fees/carnet-fee';
import { FeeType } from '../../core/models/fee-type';
import { UserPreferences } from '../../core/models/user-preference';
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
import { CommonService } from '../../core/services/common/common.service';
import { NotificationService } from '../../core/services/common/notification.service';
import { CarnetFeeService } from '../../core/services/service-provider/carnet-fee.service';
import { CarnetFeeService } from '../../core/services/fees/carnet-fee.service';
import { finalize } from 'rxjs';
@Component({
@ -29,10 +29,7 @@ export class CarnetFeeComponent implements OnInit {
this.dataSource.paginator = value;
}
@ViewChild(MatSort, { static: false })
set sort(value: MatSort) {
this.dataSource.sort = value;
}
@ViewChild(MatSort) sort!: MatSort;
displayedColumns: string[] = ['feeType', 'commissionRate', 'effectiveDate', 'actions'];
dataSource = new MatTableDataSource<CarnetFee>();
@ -176,7 +173,7 @@ export class CarnetFeeComponent implements OnInit {
? this.feeCommissionService.updateFeeCommission(this.currentFeeCommissionId, feeCommissionData)
: this.feeCommissionService.createFeeCommission(this.spid, feeCommissionData);
this.changeInProgress
this.changeInProgress = true;
saveObservable.pipe(finalize(() => {
this.changeInProgress = false;
})).subscribe({

View File

@ -10,7 +10,7 @@ import { CustomPaginator } from '../../shared/custom-paginator';
import { UserPreferences } from '../../core/models/user-preference';
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
import { NotificationService } from '../../core/services/common/notification.service';
import { ContinuationSheetFeeService } from '../../core/services/service-provider/continuation-sheet-fee.service';
import { ContinuationSheetFeeService } from '../../core/services/fees/continuation-sheet-fee.service';
@Component({
selector: 'app-continuation-sheet-fee',
@ -24,11 +24,8 @@ export class ContinuationSheetFeeComponent implements OnInit {
set paginator(value: MatPaginator) {
this.dataSource.paginator = value;
}
@ViewChild(MatSort, { static: false })
set sort(value: MatSort) {
this.dataSource.sort = value;
}
@ViewChild(MatSort) sort!: MatSort;
displayedColumns: string[] = ['customerType', 'carnetType', 'rate', 'effectiveDate', 'actions'];
dataSource = new MatTableDataSource<any>();
@ -91,8 +88,6 @@ export class ContinuationSheetFeeComponent implements OnInit {
}
loadContinuationSheets(): void {
if (!this.spid) return;
this.isLoading = true;
this.continuationSheetFeeService.getContinuationSheets(this.spid).pipe(finalize(() => {
this.isLoading = false;

View File

@ -5,12 +5,12 @@ import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { AngularMaterialModule } from '../../shared/module/angular-material.module';
import { CommonModule } from '@angular/common';
import { CounterfoilFee } from '../../core/models/service-provider/counterfoil-fee';
import { CounterfoilFee } from '../../core/models/fees/counterfoil-fee';
import { CustomPaginator } from '../../shared/custom-paginator';
import { UserPreferences } from '../../core/models/user-preference';
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
import { NotificationService } from '../../core/services/common/notification.service';
import { CounterfoilFeeService } from '../../core/services/service-provider/counterfoil-fee.service';
import { CounterfoilFeeService } from '../../core/services/fees/counterfoil-fee.service';
import { finalize } from 'rxjs';
@Component({
@ -25,11 +25,8 @@ export class CounterfoilFeeComponent implements OnInit {
set paginator(value: MatPaginator) {
this.dataSource.paginator = value;
}
@ViewChild(MatSort, { static: false })
set sort(value: MatSort) {
this.dataSource.sort = value;
}
@ViewChild(MatSort) sort!: MatSort;
displayedColumns: string[] = ['customerType', 'carnetType', 'startSets', 'endSets', 'rate', 'effectiveDate', 'actions'];
dataSource = new MatTableDataSource<any>();
@ -108,8 +105,6 @@ export class CounterfoilFeeComponent implements OnInit {
}
loadCounterfoils(): void {
if (!this.spid) return;
this.isLoading = true;
this.counterfoilFeeService.getCounterfoils(this.spid).pipe(finalize(() => {
this.isLoading = false;

View File

@ -6,7 +6,7 @@ import { MatTableDataSource } from '@angular/material/table';
import { AngularMaterialModule } from '../../shared/module/angular-material.module';
import { CommonModule } from '@angular/common';
import { CustomPaginator } from '../../shared/custom-paginator';
import { ExpeditedFee } from '../../core/models/service-provider/expedited-fee';
import { ExpeditedFee } from '../../core/models/fees/expedited-fee';
import { DeliveryType } from '../../core/models/delivery-type';
import { TimeZone } from '../../core/models/timezone';
import { finalize, Subject, takeUntil } from 'rxjs';
@ -15,7 +15,7 @@ import { ApiErrorHandlerService } from '../../core/services/common/api-error-han
import { CommonService } from '../../core/services/common/common.service';
import { NotificationService } from '../../core/services/common/notification.service';
import { TimeFormatService } from '../../core/services/common/timeformat.service';
import { ExpeditedFeeService } from '../../core/services/service-provider/expedited-fee.service';
import { ExpeditedFeeService } from '../../core/services/fees/expedited-fee.service';
@Component({
selector: 'app-expedited-fee',
@ -29,11 +29,8 @@ export class ExpeditedFeeComponent implements OnInit, OnDestroy {
set paginator(value: MatPaginator) {
this.dataSource.paginator = value;
}
@ViewChild(MatSort, { static: false })
set sort(value: MatSort) {
this.dataSource.sort = value;
}
@ViewChild(MatSort) sort!: MatSort;
displayedColumns: string[] = ['customerType', 'deliveryType', 'time', 'fee', 'effectiveDate', 'actions'];
dataSource = new MatTableDataSource<any>();

View File

@ -0,0 +1,62 @@
<h2 class="page-header">Manage Fees</h2>
<div class="manage-fees-action-buttons">
<button mat-button (click)="accordion().openAll()">Expand All</button>
<button mat-button (click)="accordion().closeAll()">Collapse All</button>
</div>
<mat-accordion class="manage-fees-headers-align" multi>
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title> Carnet Fee & Commission Setup </mat-panel-title>
</mat-expansion-panel-header>
<app-carnet-fee [spid]="spid" [isEditMode]="isEditMode" [userPreferences]="userPreferences"></app-carnet-fee>
</mat-expansion-panel>
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title> Basic Fee Setup</mat-panel-title>
</mat-expansion-panel-header>
<app-basic-fee [spid]="spid" [isEditMode]="isEditMode" [userPreferences]="userPreferences"></app-basic-fee>
</mat-expansion-panel>
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title> Counterfoil Setup</mat-panel-title>
</mat-expansion-panel-header>
<app-counterfoil-fee [spid]="spid" [isEditMode]="isEditMode"
[userPreferences]="userPreferences"></app-counterfoil-fee>
</mat-expansion-panel>
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title> Continuation Sheet Fee Setup </mat-panel-title>
</mat-expansion-panel-header>
<app-continuation-sheet-fee [spid]="spid" [isEditMode]="isEditMode"
[userPreferences]="userPreferences"></app-continuation-sheet-fee>
</mat-expansion-panel>
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title> Expedited Fee Setup</mat-panel-title>
</mat-expansion-panel-header>
<app-expedited-fee [spid]="spid" [isEditMode]="isEditMode"
[userPreferences]="userPreferences"></app-expedited-fee>
</mat-expansion-panel>
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title> Security Deposit </mat-panel-title>
</mat-expansion-panel-header>
<app-security-deposit [spid]="spid" [isEditMode]="isEditMode"
[userPreferences]="userPreferences"></app-security-deposit>
</mat-expansion-panel>
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title> Cargo Rate Setup </mat-panel-title>
</mat-expansion-panel-header>
<app-cargo-rate [spid]="spid" [isEditMode]="isEditMode" [userPreferences]="userPreferences">
</app-cargo-rate>
</mat-expansion-panel>
</mat-accordion>

View File

@ -0,0 +1,18 @@
.page-header {
margin: 0.5rem 0px;
color: var(--mat-sys-primary);
font-weight: 500;
}
.manage-fees-action-buttons {
padding-bottom: 20px;
}
.manage-fees-headers-align .mat-expansion-panel-header-description {
justify-content: space-between;
align-items: center;
}
.manage-fees-headers-align .mat-mdc-form-field+.mat-mdc-form-field {
margin-left: 8px;
}

View File

@ -0,0 +1,35 @@
import { afterNextRender, Component, viewChild } from '@angular/core';
import { AngularMaterialModule } from '../../shared/module/angular-material.module';
import { MatAccordion } from '@angular/material/expansion';
import { CarnetFeeComponent } from "../carnet-fee/carnet-fee.component";
import { BasicFeeComponent } from "../basic-fee/basic-fee.component";
import { CounterfoilFeeComponent } from "../counterfoil-fee/counterfoil-fee.component";
import { ContinuationSheetFeeComponent } from "../continuation-sheet-fee/continuation-sheet-fee.component";
import { ExpeditedFeeComponent } from "../expedited-fee/expedited-fee.component";
import { SecurityDepositComponent } from "../security-deposit/security-deposit.component";
import { UserPreferences } from '../../core/models/user-preference';
import { CommonModule } from '@angular/common';
import { UserPreferencesService } from '../../core/services/user-preference.service';
import { CargoRateComponent } from '../cargo-rate/cargo-rate.component';
@Component({
selector: 'app-manage-fee',
imports: [AngularMaterialModule, CarnetFeeComponent, BasicFeeComponent, CounterfoilFeeComponent, ContinuationSheetFeeComponent, ExpeditedFeeComponent, SecurityDepositComponent, CommonModule, CargoRateComponent],
templateUrl: './manage-fee.component.html',
styleUrl: './manage-fee.component.scss'
})
export class ManageFeeComponent {
accordion = viewChild.required(MatAccordion);
isEditMode = true;
spid = 0;
serviceProviderName: string | null = null;
userPreferences: UserPreferences;
constructor(userPrefenceService: UserPreferencesService) {
this.userPreferences = userPrefenceService.getPreferences();
afterNextRender(() => {
// Open all panels
this.accordion().openAll();
});
}
}

View File

@ -7,12 +7,12 @@ import { AngularMaterialModule } from '../../shared/module/angular-material.modu
import { CommonModule } from '@angular/common';
import { CustomPaginator } from '../../shared/custom-paginator';
import { Country } from '../../core/models/country';
import { SecurityDeposit } from '../../core/models/service-provider/security-deposit';
import { SecurityDeposit } from '../../core/models/fees/security-deposit';
import { UserPreferences } from '../../core/models/user-preference';
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
import { CommonService } from '../../core/services/common/common.service';
import { NotificationService } from '../../core/services/common/notification.service';
import { SecurityDepositService } from '../../core/services/service-provider/security-deposit.service';
import { SecurityDepositService } from '../../core/services/fees/security-deposit.service';
import { finalize } from 'rxjs';
import { HolderType } from '../../core/models/holder-type';
@ -28,11 +28,8 @@ export class SecurityDepositComponent implements OnInit {
set paginator(value: MatPaginator) {
this.dataSource.paginator = value;
}
@ViewChild(MatSort, { static: false })
set sort(value: MatSort) {
this.dataSource.sort = value;
}
@ViewChild(MatSort) sort!: MatSort;
displayedColumns: string[] = ['holderType', 'uscibMember', 'specialCommodity', 'specialCountry', 'rate', 'rateInPercentage', 'effectiveDate', 'actions'];
dataSource = new MatTableDataSource<any>();

View File

@ -38,10 +38,7 @@ export class ContactsComponent {
this.dataSource.paginator = value;
}
@ViewChild(MatSort, { static: false })
set sort(value: MatSort) {
this.dataSource.sort = value;
}
@ViewChild(MatSort) sort!: MatSort;
displayedColumns: string[] = ['firstName', 'lastName', 'title', 'phone', 'mobile', 'email', 'actions'];
dataSource = new MatTableDataSource<any>();

View File

@ -32,10 +32,7 @@ export class ContactsComponent {
this.dataSource.paginator = value;
}
@ViewChild(MatSort, { static: false })
set sort(value: MatSort) {
this.dataSource.sort = value;
}
@ViewChild(MatSort) sort!: MatSort;
displayedColumns: string[] = ['firstName', 'lastName', 'title', 'phone', 'mobile', 'email', 'defaultContact', 'actions'];
dataSource = new MatTableDataSource<any>();

View File

@ -30,10 +30,7 @@ export class LocationComponent {
this.dataSource.paginator = value;
}
@ViewChild(MatSort, { static: false })
set sort(value: MatSort) {
this.dataSource.sort = value;
}
@ViewChild(MatSort) sort!: MatSort;
displayedColumns: string[] = ['name', 'address', 'city', 'state', 'country', 'actions'];
dataSource = new MatTableDataSource<any>();

View File

@ -1,4 +1,6 @@
<div class="region-container">
<h2 class="page-header">Manage Regions</h2>
<div class="actions-bar">
<!-- <mat-slide-toggle (change)="toggleShowExpiredRecords()">
Show Expired Records

View File

@ -4,6 +4,12 @@
flex-direction: column;
gap: 24px;
.page-header {
margin: 0px;
color: var(--mat-sys-primary);
font-weight: 500;
}
.actions-bar {
clear: both;
margin-bottom: -16px;

View File

@ -26,11 +26,8 @@ export class RegionComponent implements OnInit, AfterViewInit {
set paginator(value: MatPaginator) {
this.dataSource.paginator = value;
}
@ViewChild(MatSort, { static: false })
set sort(value: MatSort) {
this.dataSource.sort = value;
}
@ViewChild(MatSort) sort!: MatSort;
displayedColumns: string[] = ['value', 'name', 'actions'];
dataSource = new MatTableDataSource<any>();

View File

@ -23,8 +23,8 @@
<mat-step [completed]="regionCompleted" [editable]="!!serviceProviderId && basicDetailsCompleted">
<ng-template matStepLabel>Regions</ng-template>
<app-region *ngIf="serviceProviderId" [spid]="serviceProviderId" (hasRegions)="onRegionsSaved($event)">
</app-region>
<app-sp-region *ngIf="serviceProviderId" [spid]="serviceProviderId" (hasRegions)="onRegionsSaved($event)">
</app-sp-region>
</mat-step>
<!-- Carnet Sequence Step -->

View File

@ -5,16 +5,16 @@ import { AngularMaterialModule } from '../../shared/module/angular-material.modu
import { CommonModule } from '@angular/common';
import { ContactsComponent } from '../contacts/contacts.component';
import { CarnetSequenceComponent } from '../carnet-sequence/carnet-sequence.component';
import { CarnetFeeComponent } from '../carnet-fee/carnet-fee.component';
import { BasicFeeComponent } from '../basic-fee/basic-fee.component';
import { CounterfoilFeeComponent } from '../counterfoil-fee/counterfoil-fee.component';
import { ExpeditedFeeComponent } from '../expedited-fee/expedited-fee.component';
import { SecurityDepositComponent } from '../security-deposit/security-deposit.component';
import { ContinuationSheetFeeComponent } from "../continuation-sheet-fee/continuation-sheet-fee.component";
import { CarnetFeeComponent } from '../../fees/carnet-fee/carnet-fee.component';
import { BasicFeeComponent } from '../../fees/basic-fee/basic-fee.component';
import { CounterfoilFeeComponent } from '../../fees/counterfoil-fee/counterfoil-fee.component';
import { ExpeditedFeeComponent } from '../../fees/expedited-fee/expedited-fee.component';
import { SecurityDepositComponent } from '../../fees/security-deposit/security-deposit.component';
import { ContinuationSheetFeeComponent } from "../../fees/continuation-sheet-fee/continuation-sheet-fee.component";
import { UserPreferences } from '../../core/models/user-preference';
import { UserPreferencesService } from '../../core/services/user-preference.service';
import { CargoRateComponent } from '../cargo-rate/cargo-rate.component';
import { RegionComponent } from '../../region/region.component';
import { CargoRateComponent } from '../../fees/cargo-rate/cargo-rate.component';
import { RegionComponent } from '../region/region.component';
@Component({
selector: 'app-add-service-provider',

View File

@ -27,11 +27,8 @@ export class CarnetSequenceComponent implements OnInit {
set paginator(value: MatPaginator) {
this.dataSource.paginator = value;
}
@ViewChild(MatSort, { static: false })
set sort(value: MatSort) {
this.dataSource.sort = value;
}
@ViewChild(MatSort) sort!: MatSort;
displayedColumns: string[] = ['carnetType', 'region', 'startNumber', 'endNumber', 'lastNumber'];
dataSource = new MatTableDataSource<CarnetSequence>();

View File

@ -29,11 +29,8 @@ export class ContactsComponent implements OnInit {
set paginator(value: MatPaginator) {
this.dataSource.paginator = value;
}
@ViewChild(MatSort, { static: false })
set sort(value: MatSort) {
this.dataSource.sort = value;
}
@ViewChild(MatSort) sort!: MatSort;
displayedColumns: string[] = ['firstName', 'lastName', 'title', 'phone', 'email', 'defaultContact', 'actions'];
dataSource = new MatTableDataSource<any>();

View File

@ -24,7 +24,7 @@
<mat-expansion-panel-header>
<mat-panel-title> Regions </mat-panel-title>
</mat-expansion-panel-header>
<app-region [spid]="spid"></app-region>
<app-sp-region [spid]="spid"></app-sp-region>
</mat-expansion-panel>
<mat-expansion-panel>

View File

@ -5,17 +5,17 @@ import { BasicDetailsComponent } from '../basic-details/basic-details.component'
import { ContactsComponent } from '../contacts/contacts.component';
import { ActivatedRoute } from '@angular/router';
import { CarnetSequenceComponent } from '../carnet-sequence/carnet-sequence.component';
import { CarnetFeeComponent } from "../carnet-fee/carnet-fee.component";
import { BasicFeeComponent } from "../basic-fee/basic-fee.component";
import { CounterfoilFeeComponent } from "../counterfoil-fee/counterfoil-fee.component";
import { ContinuationSheetFeeComponent } from "../continuation-sheet-fee/continuation-sheet-fee.component";
import { ExpeditedFeeComponent } from "../expedited-fee/expedited-fee.component";
import { SecurityDepositComponent } from "../security-deposit/security-deposit.component";
import { CarnetFeeComponent } from "../../fees/carnet-fee/carnet-fee.component";
import { BasicFeeComponent } from "../../fees/basic-fee/basic-fee.component";
import { CounterfoilFeeComponent } from "../../fees/counterfoil-fee/counterfoil-fee.component";
import { ContinuationSheetFeeComponent } from "../../fees/continuation-sheet-fee/continuation-sheet-fee.component";
import { ExpeditedFeeComponent } from "../../fees/expedited-fee/expedited-fee.component";
import { SecurityDepositComponent } from "../../fees/security-deposit/security-deposit.component";
import { UserPreferences } from '../../core/models/user-preference';
import { CommonModule } from '@angular/common';
import { UserPreferencesService } from '../../core/services/user-preference.service';
import { CargoRateComponent } from '../cargo-rate/cargo-rate.component';
import { RegionComponent } from '../../region/region.component';
import { CargoRateComponent } from '../../fees/cargo-rate/cargo-rate.component';
import { RegionComponent } from '../region/region.component';
@Component({
selector: 'app-edit-service-provider',

View File

@ -0,0 +1,55 @@
<div class="region-container">
<div class="loading-shade" *ngIf="isLoading">
<mat-spinner diameter="50"></mat-spinner>
</div>
<div class="region-selection-container">
<!-- Available Regions Listbox -->
<div class="available-regions">
<h3>Available Regions</h3>
<mat-selection-list [multiple]="false" hideSingleSelectionIndicator>
<mat-list-option *ngFor="let region of regions" [value]="region" [disabled]="isRegionSelected(region)"
(click)="onAvailableRegionSelection(availableoption)" #availableoption>
{{region.name}}
</mat-list-option>
</mat-selection-list>
</div>
<!-- Controls -->
<div class="controls">
<div class="action-buttons">
<button mat-raised-button color="primary" type="button" (click)="addRegion()" class="icon-end">
<mat-icon>keyboard_double_arrow_right</mat-icon>
<span> Add</span>
</button>
<button mat-raised-button type="button" (click)="removeRegion()">
<mat-icon>keyboard_double_arrow_left</mat-icon>
<span> Remove</span>
</button>
</div>
</div>
<!-- Selected Regions -->
<div class="selected-regions">
<div class="regions">
<h3>Selected Regions</h3>
<mat-selection-list [multiple]="false" hideSingleSelectionIndicator>
<mat-list-option *ngFor="let region of selectedRegions" [value]="region"
(click)="onRegionSelection(selectedoption)" #selectedoption>
{{region.name}}
</mat-list-option>
<mat-list-item *ngIf="selectedRegions.length === 0">
<span class="empty-message">No regions selected</span>
</mat-list-item>
</mat-selection-list>
</div>
</div>
</div>
<div class="form-actions">
<button mat-raised-button color="primary" type="submit" (click)="onSubmit()"
[disabled]="changeInProgress || selectedRegions.length === 0">
Save
</button>
</div>
</div>

View File

@ -0,0 +1,90 @@
.region-container {
padding: 0.75rem 0 0 0;
margin: 0 auto;
.region-selection-container {
display: flex;
gap: 24px;
margin-bottom: 12px;
// border: 1px solid;
// border-radius: 4px;
// padding: 20px;
@media (max-width: 768px) {
flex-direction: column;
}
}
.available-regions,
.selected-regions {
flex: 1;
border: 1px solid #e0e0e0;
border-radius: 4px;
padding: 16px;
overflow: hidden;
h3 {
margin: 0 0 16px 0;
font-size: 0.875rem;
font-weight: 500;
}
mat-selection-list {
height: 150px;
overflow-y: auto;
padding: 0;
mat-list-item {
.empty-message {
font-style: italic;
}
}
}
}
.controls {
display: flex;
flex-direction: column;
gap: 16px;
width: 150px;
padding: 16px;
.action-buttons {
display: flex;
flex-direction: column;
gap: 8px;
button {
width: 100%;
display: flex;
// gap: 8px;
align-items: center;
}
mat-icon {
margin: 0;
}
button.icon-end {
flex-direction: row-reverse;
}
}
}
.selected-regions {
display: flex;
flex-direction: column;
gap: 16px;
.regions {
flex: 1;
}
}
.form-actions {
display: flex;
justify-content: flex-end;
padding-top: 12px;
border-top: 1px solid #e0e0e0;
}
}

View File

@ -0,0 +1,133 @@
import { Component, EventEmitter, inject, Input, Output } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { finalize, Subject, takeUntil } from 'rxjs';
import { ApiErrorHandlerService } from '../../core/services/common/api-error-handler.service';
import { NotificationService } from '../../core/services/common/notification.service';
import { AngularMaterialModule } from '../../shared/module/angular-material.module';
import { CommonModule } from '@angular/common';
import { MatListModule } from '@angular/material/list';
import { RegionService } from '../../core/services/region/region.service';
import { Region } from '../../core/models/region/region';
@Component({
selector: 'app-sp-region',
imports: [AngularMaterialModule, ReactiveFormsModule, CommonModule, MatListModule],
templateUrl: './region.component.html',
styleUrl: './region.component.scss'
})
export class RegionComponent {
@Input() spid: number = 0;
@Input() isEditMode = false;
@Output() hasRegions = new EventEmitter<boolean>();
private destroy$ = new Subject<void>();
private notificationService = inject(NotificationService);
private errorHandler = inject(ApiErrorHandlerService);
private regionService = inject(RegionService);
isLoading = false;
changeInProgress = false;
regions: Region[] = [];
selectedRegions: Region[] = [];
// Currently selected region in the listbox
selectedAvailableRegion: Region | null = null;
selectedRegion: Region | null = null;
constructor() {
}
ngOnInit(): void {
this.loadRegions(0);
this.loadRegions(this.spid);
}
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}
loadRegions(spid: number): void {
this.isLoading = true;
this.regionService.getRegions(spid)
.pipe(takeUntil(this.destroy$), finalize(() => {
this.isLoading = false;
}))
.subscribe({
next: (regions) => {
if (spid === 0) {
this.regions = regions;
} else {
this.selectedRegions = regions;
}
},
error: (error) => {
console.error('Failed to load regions', error);
}
});
}
onAvailableRegionSelection(event: any) {
this.selectedAvailableRegion = event.value;
}
onRegionSelection(event: any) {
this.selectedRegion = event.value;
}
// Add selected region
addRegion(): void {
if (!this.selectedAvailableRegion) return;
const existingIndex = this.selectedRegions.findIndex(
c => c.value === this.selectedAvailableRegion!.value
);
if (existingIndex === -1) {
this.selectedRegions.push({
...this.selectedAvailableRegion
});
}
}
// Remove region
removeRegion(): void {
if (!this.selectedRegion) return;
this.selectedRegions = this.selectedRegions.filter(
c => c.value !== this.selectedRegion!.value
);
}
// Check if a region is already selected
isRegionSelected(region: Region): boolean {
return this.selectedRegions.some(c => c.value === region.value)
}
onSubmit(): void {
const region: Region = {
id: 0,
value: this.selectedRegions.map(r => r.value).join(','),
name: this.selectedRegions.map(r => r.name).join(',')
};
this.changeInProgress = true;
this.regionService.createRegion(region, this.spid).pipe(finalize(() => {
this.changeInProgress = false;
})).subscribe({
next: () => {
this.notificationService.showSuccess('Regions saved successfully');
this.hasRegions.emit(true);
},
error: (error) => {
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to save regions');
this.notificationService.showError(errorMessage);
console.error('Error saving region data : ', error);
}
});
}
}

View File

@ -1,6 +1,6 @@
export const environment = {
production: false,
apiUrl: 'https://dev.alphaomegainfosys.com/test-api',
apiDb: '1',
appType: 'service-provider'
apiUrl: 'https://dev.alphaomegainfosys.com/test-api-2',
apiDb: '2',
appType: 'service-provider',
};