feedback updates

This commit is contained in:
Cyril Joseph 2025-11-13 23:38:54 -04:00
parent 76d78c5869
commit 62b78cd01a
32 changed files with 144 additions and 40 deletions

View File

@ -0,0 +1,5 @@
export interface ContactTitle {
name: string;
id: string;
value: string;
}

View File

@ -7,5 +7,6 @@ export interface BasicFee {
spid?: number; spid?: number;
dateCreated?: Date | null; dateCreated?: Date | null;
createdBy?: string | null; createdBy?: string | null;
expiredDate?: Date | null;
expired?: boolean; expired?: boolean;
} }

View File

@ -8,5 +8,6 @@ export interface CargoRate {
rate: number, rate: number,
dateCreated?: Date | null; dateCreated?: Date | null;
createdBy?: string | null; createdBy?: string | null;
expiredDate?: Date | null;
expired?: boolean; expired?: boolean;
} }

View File

@ -6,5 +6,6 @@ export interface CarnetFee {
spid: number; spid: number;
dateCreated?: Date | null; dateCreated?: Date | null;
createdBy?: string | null; createdBy?: string | null;
expiredDate?: Date | null;
expired?: boolean; expired?: boolean;
} }

View File

@ -7,5 +7,6 @@ export interface ContinuationSheetFee {
carnetType: string; carnetType: string;
dateCreated?: Date | null; dateCreated?: Date | null;
createdBy?: string | null; createdBy?: string | null;
expiredDate?: Date | null;
expired?: boolean; expired?: boolean;
} }

View File

@ -9,5 +9,6 @@ export interface CounterfoilFee {
rate: number, rate: number,
dateCreated?: Date | null; dateCreated?: Date | null;
createdBy?: string | null; createdBy?: string | null;
expiredDate?: Date | null;
expired?: boolean; expired?: boolean;
} }

View File

@ -9,5 +9,6 @@ export interface ExpeditedFee {
effectiveDate: Date; effectiveDate: Date;
dateCreated?: Date | null; dateCreated?: Date | null;
createdBy?: string | null; createdBy?: string | null;
expiredDate?: Date | null;
expired?: boolean; expired?: boolean;
} }

View File

@ -1,7 +1,7 @@
export interface SecurityDeposit { export interface SecurityDeposit {
securityDepositId: number; securityDepositId: number;
holderType: string; holderType: string;
uscibMember: boolean; uscibMember: string;
specialCommodity: string; specialCommodity: string;
specialCountry: string; specialCountry: string;
rate: number; rate: number;
@ -10,5 +10,6 @@ export interface SecurityDeposit {
spid: number; spid: number;
dateCreated?: Date | null; dateCreated?: Date | null;
createdBy?: string | null; createdBy?: string | null;
expiredDate?: Date | null;
expired?: boolean; expired?: boolean;
} }

View File

@ -14,6 +14,7 @@ import { CarnetStatus } from '../../models/carnet-status';
import { Country } from '../../models/country'; import { Country } from '../../models/country';
import { UserService } from './user.service'; import { UserService } from './user.service';
import { HolderType } from '../../models/holder-type'; import { HolderType } from '../../models/holder-type';
import { ContactTitle } from '../../models/contact-title';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
@ -163,6 +164,18 @@ export class CommonService {
); );
} }
getContactTitles(): Observable<ContactTitle[]> {
return this.http.get<any[]>(`${this.apiUrl}/${this.apiDb}/GetParamValues?P_PARAMTYPE=012&P_SPID=${this.userService.getUserSpid()}`).pipe(
map((response) =>
response.map((item) => ({
name: item.PARAMDESC,
id: item.PARAMID,
value: item.PARAMVALUE,
}))
)
);
}
formatUSDate(datetime: Date): string { formatUSDate(datetime: Date): string {
const date = new Date(datetime); const date = new Date(datetime);
const month = String(date.getUTCMonth() + 1).padStart(2, '0'); const month = String(date.getUTCMonth() + 1).padStart(2, '0');

View File

@ -31,6 +31,7 @@ export class BasicFeeService {
effectiveDate: item.EFFDATE, effectiveDate: item.EFFDATE,
createdBy: item.CREATEDBY || null, createdBy: item.CREATEDBY || null,
dateCreated: item.DATECREATED || null, dateCreated: item.DATECREATED || null,
expiredDate: item.EXPDATE || null,
expired: item.EXPDATE ? new Date(item.EXPDATE) < new Date() : false expired: item.EXPDATE ? new Date(item.EXPDATE) < new Date() : false
})); }));
} }

View File

@ -33,6 +33,7 @@ export class CargoRateService {
rate: item.RATE, rate: item.RATE,
createdBy: item.CREATEDBY || null, createdBy: item.CREATEDBY || null,
dateCreated: item.DATECREATED || null, dateCreated: item.DATECREATED || null,
expiredDate: item.EXPDATE || null,
expired: item.EXPDATE ? new Date(item.EXPDATE) < new Date() : false expired: item.EXPDATE ? new Date(item.EXPDATE) < new Date() : false
})); }));
} }

View File

@ -32,6 +32,7 @@ export class CarnetFeeService {
spid: item.SPID, spid: item.SPID,
createdBy: item.CREATEDBY || null, createdBy: item.CREATEDBY || null,
dateCreated: item.DATECREATED || null, dateCreated: item.DATECREATED || null,
expiredDate: item.EXPDATE || null,
expired: item.EXPDATE ? new Date(item.EXPDATE) < new Date() : false expired: item.EXPDATE ? new Date(item.EXPDATE) < new Date() : false
})); }));
} }

View File

@ -32,6 +32,7 @@ export class ContinuationSheetFeeService {
rate: item.RATE, rate: item.RATE,
createdBy: item.CREATEDBY || null, createdBy: item.CREATEDBY || null,
dateCreated: item.DATECREATED || null, dateCreated: item.DATECREATED || null,
expiredDate: item.EXPDATE || null,
expired: item.EXPDATE ? new Date(item.EXPDATE) < new Date() : false expired: item.EXPDATE ? new Date(item.EXPDATE) < new Date() : false
})); }));
} }

View File

@ -34,6 +34,7 @@ export class CounterfoilFeeService {
rate: item.RATE, rate: item.RATE,
createdBy: item.CREATEDBY || null, createdBy: item.CREATEDBY || null,
dateCreated: item.DATECREATED || null, dateCreated: item.DATECREATED || null,
expiredDate: item.EXPDATE || null,
expired: item.EXPDATE ? new Date(item.EXPDATE) < new Date() : false expired: item.EXPDATE ? new Date(item.EXPDATE) < new Date() : false
})); }));
} }

View File

@ -35,6 +35,7 @@ export class ExpeditedFeeService {
spid: item.SPID, spid: item.SPID,
createdBy: item.CREATEDBY || null, createdBy: item.CREATEDBY || null,
dateCreated: item.DATECREATED || null, dateCreated: item.DATECREATED || null,
expiredDate: item.EXPDATE || null,
expired: item.EXPDATE ? new Date(item.EXPDATE) < new Date() : false expired: item.EXPDATE ? new Date(item.EXPDATE) < new Date() : false
})); }));
} }

View File

@ -35,6 +35,7 @@ export class SecurityDepositService {
spid: item.SPID, spid: item.SPID,
createdBy: item.CREATEDBY || null, createdBy: item.CREATEDBY || null,
dateCreated: item.DATECREATED || null, dateCreated: item.DATECREATED || null,
expiredDate: item.EXPDATE || null,
expired: item.EXPDATE ? new Date(item.EXPDATE) < new Date() : false expired: item.EXPDATE ? new Date(item.EXPDATE) < new Date() : false
})); }));
} }
@ -45,7 +46,7 @@ export class SecurityDepositService {
P_SPID: spid, P_SPID: spid,
P_EFFDATE: this.commonService.formatUSDate(data.effectiveDate), P_EFFDATE: this.commonService.formatUSDate(data.effectiveDate),
P_HOLDERTYPE: data.holderType, P_HOLDERTYPE: data.holderType,
P_USCIBMEMBERFLAG: data.uscibMember ? 'Y' : 'N', P_USCIBMEMBERFLAG: data.uscibMember,
P_SPCLCOMMODITY: data.specialCommodity, P_SPCLCOMMODITY: data.specialCommodity,
P_SPCLCOUNTRY: data.specialCountry, P_SPCLCOUNTRY: data.specialCountry,
P_RATE: data.rate, P_RATE: data.rate,

View File

@ -37,6 +37,12 @@
<td mat-cell *matCellDef="let fee">{{ fee.effectiveDate | date:'mediumDate':'UTC' }}</td> <td mat-cell *matCellDef="let fee">{{ fee.effectiveDate | date:'mediumDate':'UTC' }}</td>
</ng-container> </ng-container>
<!-- Expired Date Column -->
<ng-container matColumnDef="expiredDate">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Expired Date</th>
<td mat-cell *matCellDef="let fee">{{ fee.expiredDate | date:'mediumDate':'UTC' }}</td>
</ng-container>
<!-- Actions Column --> <!-- Actions Column -->
<ng-container matColumnDef="actions"> <ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef>Actions</th> <th mat-header-cell *matHeaderCellDef>Actions</th>

View File

@ -28,7 +28,7 @@ export class BasicFeeComponent {
@ViewChild(MatSort) sort!: MatSort; @ViewChild(MatSort) sort!: MatSort;
displayedColumns: string[] = ['startCarnetValue', 'endCarnetValue', 'fees', 'effectiveDate', 'actions']; displayedColumns: string[] = ['startCarnetValue', 'endCarnetValue', 'fees', 'effectiveDate', 'expiredDate', 'actions'];
dataSource = new MatTableDataSource<BasicFee>(); dataSource = new MatTableDataSource<BasicFee>();
feeForm: FormGroup; feeForm: FormGroup;
isEditing = false; isEditing = false;

View File

@ -49,6 +49,12 @@
</td> </td>
</ng-container> </ng-container>
<!-- Expired Date Column -->
<ng-container matColumnDef="expiredDate">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Expired Date</th>
<td mat-cell *matCellDef="let fee">{{ fee.expiredDate | date:'mediumDate':'UTC' }}</td>
</ng-container>
<!-- Actions Column --> <!-- Actions Column -->
<ng-container matColumnDef="actions"> <ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef>Actions</th> <th mat-header-cell *matHeaderCellDef>Actions</th>

View File

@ -28,7 +28,7 @@ export class CargoRateComponent implements OnInit {
@ViewChild(MatSort) sort!: MatSort; @ViewChild(MatSort) sort!: MatSort;
displayedColumns: string[] = ['carnetType', 'startSets', 'endSets', 'rate', 'effectiveDate', 'actions']; displayedColumns: string[] = ['carnetType', 'startSets', 'endSets', 'rate', 'effectiveDate', 'expiredDate', 'actions'];
dataSource = new MatTableDataSource<any>(); dataSource = new MatTableDataSource<any>();
cargoRateForm: FormGroup; cargoRateForm: FormGroup;
isEditing = false; isEditing = false;

View File

@ -23,7 +23,7 @@
<!-- Commission Rate Column --> <!-- Commission Rate Column -->
<ng-container matColumnDef="commissionRate"> <ng-container matColumnDef="commissionRate">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Commission Rate</th> <th mat-header-cell *matHeaderCellDef mat-sort-header>Commission Rate</th>
<td mat-cell *matCellDef="let item">{{ item.commissionRate }}</td> <td mat-cell *matCellDef="let item">{{ item.commissionRate | number:'1.2-2' }}</td>
</ng-container> </ng-container>
<!-- Effective Date Column --> <!-- Effective Date Column -->
@ -32,6 +32,12 @@
<td mat-cell *matCellDef="let item">{{ item.effectiveDate | date:'mediumDate':'UTC' }}</td> <td mat-cell *matCellDef="let item">{{ item.effectiveDate | date:'mediumDate':'UTC' }}</td>
</ng-container> </ng-container>
<!-- Expired Date Column -->
<ng-container matColumnDef="expiredDate">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Expired Date</th>
<td mat-cell *matCellDef="let fee">{{ fee.expiredDate | date:'mediumDate':'UTC' }}</td>
</ng-container>
<!-- Actions Column --> <!-- Actions Column -->
<ng-container matColumnDef="actions"> <ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef>Actions</th> <th mat-header-cell *matHeaderCellDef>Actions</th>
@ -87,6 +93,9 @@
<mat-error *ngIf="feeCommissionForm.get('commissionRate')?.errors?.['required']"> <mat-error *ngIf="feeCommissionForm.get('commissionRate')?.errors?.['required']">
Commission rate is required Commission rate is required
</mat-error> </mat-error>
<mat-error *ngIf="feeCommissionForm.get('commissionRate')?.errors?.['pattern']">
Please enter a valid number with up to 2 decimal places
</mat-error>
</mat-form-field> </mat-form-field>
<mat-form-field appearance="outline"> <mat-form-field appearance="outline">

View File

@ -31,7 +31,7 @@ export class CarnetFeeComponent implements OnInit {
@ViewChild(MatSort) sort!: MatSort; @ViewChild(MatSort) sort!: MatSort;
displayedColumns: string[] = ['feeType', 'commissionRate', 'effectiveDate', 'actions']; displayedColumns: string[] = ['feeType', 'commissionRate', 'effectiveDate', 'expiredDate', 'actions'];
dataSource = new MatTableDataSource<CarnetFee>(); dataSource = new MatTableDataSource<CarnetFee>();
feeCommissionForm: FormGroup; feeCommissionForm: FormGroup;
isEditing = false; isEditing = false;
@ -62,7 +62,7 @@ export class CarnetFeeComponent implements OnInit {
constructor() { constructor() {
this.feeCommissionForm = this.fb.group({ this.feeCommissionForm = this.fb.group({
feeType: ['', Validators.required], feeType: ['', Validators.required],
commissionRate: [0, [Validators.required]], commissionRate: [0, [Validators.required, Validators.pattern(/^\d+\.?\d{0,2}$/)]],
effectiveDate: ['', Validators.required] effectiveDate: ['', Validators.required]
}); });
} }

View File

@ -44,6 +44,12 @@
</td> </td>
</ng-container> </ng-container>
<!-- Expired Date Column -->
<ng-container matColumnDef="expiredDate">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Expired Date</th>
<td mat-cell *matCellDef="let fee">{{ fee.expiredDate | date:'mediumDate':'UTC' }}</td>
</ng-container>
<!-- Actions Column --> <!-- Actions Column -->
<ng-container matColumnDef="actions"> <ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef>Actions</th> <th mat-header-cell *matHeaderCellDef>Actions</th>

View File

@ -27,7 +27,7 @@ export class ContinuationSheetFeeComponent implements OnInit {
@ViewChild(MatSort) sort!: MatSort; @ViewChild(MatSort) sort!: MatSort;
displayedColumns: string[] = ['customerType', 'carnetType', 'rate', 'effectiveDate', 'actions']; displayedColumns: string[] = ['customerType', 'carnetType', 'rate', 'effectiveDate', 'expiredDate', 'actions'];
dataSource = new MatTableDataSource<any>(); dataSource = new MatTableDataSource<any>();
continuationSheetForm: FormGroup; continuationSheetForm: FormGroup;
isEditing = false; isEditing = false;

View File

@ -56,6 +56,12 @@
</td> </td>
</ng-container> </ng-container>
<!-- Expired Date Column -->
<ng-container matColumnDef="expiredDate">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Expired Date</th>
<td mat-cell *matCellDef="let fee">{{ fee.expiredDate | date:'mediumDate':'UTC' }}</td>
</ng-container>
<!-- Actions Column --> <!-- Actions Column -->
<ng-container matColumnDef="actions"> <ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef>Actions</th> <th mat-header-cell *matHeaderCellDef>Actions</th>

View File

@ -28,7 +28,7 @@ export class CounterfoilFeeComponent implements OnInit {
@ViewChild(MatSort) sort!: MatSort; @ViewChild(MatSort) sort!: MatSort;
displayedColumns: string[] = ['customerType', 'carnetType', 'startSets', 'endSets', 'rate', 'effectiveDate', 'actions']; displayedColumns: string[] = ['customerType', 'carnetType', 'startSets', 'endSets', 'rate', 'effectiveDate', 'expiredDate', 'actions'];
dataSource = new MatTableDataSource<any>(); dataSource = new MatTableDataSource<any>();
counterfoilForm: FormGroup; counterfoilForm: FormGroup;
isEditing = false; isEditing = false;

View File

@ -44,6 +44,12 @@
<td mat-cell *matCellDef="let fee">{{ fee.effectiveDate | date:'mediumDate':'UTC' }}</td> <td mat-cell *matCellDef="let fee">{{ fee.effectiveDate | date:'mediumDate':'UTC' }}</td>
</ng-container> </ng-container>
<!-- Expired Date Column -->
<ng-container matColumnDef="expiredDate">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Expired Date</th>
<td mat-cell *matCellDef="let fee">{{ fee.expiredDate | date:'mediumDate':'UTC' }}</td>
</ng-container>
<!-- Actions Column --> <!-- Actions Column -->
<ng-container matColumnDef="actions"> <ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef>Actions</th> <th mat-header-cell *matHeaderCellDef>Actions</th>

View File

@ -32,7 +32,7 @@ export class ExpeditedFeeComponent implements OnInit, OnDestroy {
@ViewChild(MatSort) sort!: MatSort; @ViewChild(MatSort) sort!: MatSort;
displayedColumns: string[] = ['customerType', 'deliveryType', 'time', 'fee', 'effectiveDate', 'actions']; displayedColumns: string[] = ['customerType', 'deliveryType', 'time', 'fee', 'effectiveDate', 'expiredDate', 'actions'];
dataSource = new MatTableDataSource<any>(); dataSource = new MatTableDataSource<any>();
feeForm: FormGroup; feeForm: FormGroup;
isEditing = false; isEditing = false;

View File

@ -24,22 +24,20 @@
<ng-container matColumnDef="uscibMember"> <ng-container matColumnDef="uscibMember">
<th mat-header-cell *matHeaderCellDef mat-sort-header>USCIB Member</th> <th mat-header-cell *matHeaderCellDef mat-sort-header>USCIB Member</th>
<td mat-cell *matCellDef="let deposit"> <td mat-cell *matCellDef="let deposit">
<mat-icon [color]="deposit.uscibMember ? 'primary' : ''"> {{ deposit.uscibMember }}
{{ deposit.uscibMember ? 'check_circle' : 'cancel' }}
</mat-icon>
</td> </td>
</ng-container> </ng-container>
<!-- Special Commodity Column --> <!-- Special Commodity Column -->
<ng-container matColumnDef="specialCommodity"> <ng-container matColumnDef="specialCommodity">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Special Commodity</th> <th mat-header-cell *matHeaderCellDef mat-sort-header>Special Commodity</th>
<td mat-cell *matCellDef="let deposit">{{ deposit.specialCommodity || 'N/A' }}</td> <td mat-cell *matCellDef="let deposit">{{ deposit.specialCommodity }}</td>
</ng-container> </ng-container>
<!-- Special Country Column --> <!-- Special Country Column -->
<ng-container matColumnDef="specialCountry"> <ng-container matColumnDef="specialCountry">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Special Country</th> <th mat-header-cell *matHeaderCellDef mat-sort-header>Special Country</th>
<td mat-cell *matCellDef="let deposit">{{ getCountryName(deposit.specialCountry) || 'N/A' }}</td> <td mat-cell *matCellDef="let deposit">{{ getCountryName(deposit.specialCountry) }}</td>
</ng-container> </ng-container>
<!-- Rate Column --> <!-- Rate Column -->
@ -60,6 +58,12 @@
<td mat-cell *matCellDef="let deposit">{{ deposit.effectiveDate | date:'mediumDate':'UTC' }}</td> <td mat-cell *matCellDef="let deposit">{{ deposit.effectiveDate | date:'mediumDate':'UTC' }}</td>
</ng-container> </ng-container>
<!-- Expired Date Column -->
<ng-container matColumnDef="expiredDate">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Expired Date</th>
<td mat-cell *matCellDef="let fee">{{ fee.expiredDate | date:'mediumDate':'UTC' }}</td>
</ng-container>
<!-- Actions Column --> <!-- Actions Column -->
<ng-container matColumnDef="actions"> <ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef>Actions</th> <th mat-header-cell *matHeaderCellDef>Actions</th>
@ -101,20 +105,20 @@
<div class="form-row"> <div class="form-row">
<mat-label>Holder Type</mat-label> <mat-label>Holder Type</mat-label>
<mat-radio-group formControlName="holderType" required class="horizontal-group"> <mat-radio-group formControlName="holderType" class="horizontal-group">
<mat-radio-button *ngFor="let type of holderTypes" [value]="type.value" class="radio-button"> <mat-radio-button *ngFor="let type of holderTypes" [value]="type.value" class="radio-button">
{{ type.name }} {{ type.name }}
</mat-radio-button> </mat-radio-button>
</mat-radio-group> </mat-radio-group>
<mat-error *ngIf="depositForm.get('holderType')?.errors?.['required']"> <!-- <mat-error *ngIf="depositForm.get('holderType')?.errors?.['required']">
Holder type is required Holder type is required
</mat-error> </mat-error> -->
</div> </div>
<div class="form-row"> <div class="form-row">
<mat-label>USCIB Member</mat-label> <mat-label>USCIB Member</mat-label>
<mat-radio-group formControlName="uscibMember" required class="horizontal-group"> <mat-radio-group formControlName="uscibMember" required class="horizontal-group">
<mat-radio-button *ngFor="let type of yesNoOptions" [value]="type.value" class="radio-button"> <mat-radio-button *ngFor="let type of uscibMemberOptions" [value]="type.value" class="radio-button">
{{ type.label }} {{ type.label }}
</mat-radio-button> </mat-radio-button>
</mat-radio-group> </mat-radio-group>

View File

@ -31,7 +31,7 @@ export class SecurityDepositComponent implements OnInit {
@ViewChild(MatSort) sort!: MatSort; @ViewChild(MatSort) sort!: MatSort;
displayedColumns: string[] = ['holderType', 'uscibMember', 'specialCommodity', 'specialCountry', 'rate', 'rateType', 'effectiveDate', 'actions']; displayedColumns: string[] = ['holderType', 'uscibMember', 'specialCommodity', 'specialCountry', 'rate', 'rateType', 'effectiveDate', 'expiredDate', 'actions'];
dataSource = new MatTableDataSource<any>(); dataSource = new MatTableDataSource<any>();
depositForm: FormGroup; depositForm: FormGroup;
isEditing = false; isEditing = false;
@ -55,9 +55,10 @@ export class SecurityDepositComponent implements OnInit {
@Input() userPreferences!: UserPreferences; @Input() userPreferences!: UserPreferences;
@Output() hasSecurityDeposits = new EventEmitter<boolean>(); @Output() hasSecurityDeposits = new EventEmitter<boolean>();
yesNoOptions = [ uscibMemberOptions = [
{ value: 'Y', label: 'Yes' }, { value: 'Yes', label: 'Yes' },
{ value: 'N', label: 'No' } { value: 'No', label: 'No' },
{ value: 'Both', label: 'Both' }
]; ];
private fb = inject(FormBuilder); private fb = inject(FormBuilder);
@ -68,8 +69,8 @@ export class SecurityDepositComponent implements OnInit {
constructor() { constructor() {
this.depositForm = this.fb.group({ this.depositForm = this.fb.group({
holderType: ['CORP', Validators.required], holderType: ['CORP'],
uscibMember: ['Y', Validators.required], uscibMember: ['Yes', Validators.required],
specialCommodity: [''], specialCommodity: [''],
specialCountry: [''], specialCountry: [''],
rate: [0, [Validators.required, Validators.min(0)]], rate: [0, [Validators.required, Validators.min(0)]],
@ -134,7 +135,7 @@ export class SecurityDepositComponent implements OnInit {
loadHolderTypes(): void { loadHolderTypes(): void {
this.commonService.getHolderTypes().subscribe({ this.commonService.getHolderTypes().subscribe({
next: (holderTypes) => { next: (holderTypes) => {
this.holderTypes = holderTypes; this.holderTypes = [...holderTypes, { value: '', name: 'All', id: "0" }];
}, },
error: (error) => { error: (error) => {
console.error('Error loading holder types:', error); console.error('Error loading holder types:', error);
@ -156,7 +157,7 @@ export class SecurityDepositComponent implements OnInit {
this.currentDepositId = null; this.currentDepositId = null;
this.depositForm.reset({ this.depositForm.reset({
holderType: 'CORP', holderType: 'CORP',
uscibMember: 'N', uscibMember: 'No',
specialCountry: '', specialCountry: '',
}); });
this.depositForm.patchValue({ rate: 0 }); this.depositForm.patchValue({ rate: 0 });
@ -173,7 +174,7 @@ export class SecurityDepositComponent implements OnInit {
this.currentDepositId = deposit.securityDepositId; this.currentDepositId = deposit.securityDepositId;
this.depositForm.patchValue({ this.depositForm.patchValue({
holderType: deposit.holderType, holderType: deposit.holderType,
uscibMember: deposit.uscibMember ? 'Y' : 'N', uscibMember: deposit.uscibMember,
specialCommodity: deposit.specialCommodity, specialCommodity: deposit.specialCommodity,
specialCountry: deposit.specialCountry, specialCountry: deposit.specialCountry,
rate: deposit.rate, rate: deposit.rate,
@ -198,7 +199,6 @@ export class SecurityDepositComponent implements OnInit {
const depositData = { const depositData = {
...this.depositForm.value, ...this.depositForm.value,
uscibMember: this.depositForm.value.uscibMember === 'Y',
specialCommodity: this.depositForm.value.specialCommodity || null, specialCommodity: this.depositForm.value.specialCommodity || null,
specialCountry: this.depositForm.value.specialCountry || null specialCountry: this.depositForm.value.specialCountry || null
}; };
@ -257,7 +257,7 @@ export class SecurityDepositComponent implements OnInit {
this.currentDepositId = null; this.currentDepositId = null;
this.depositForm.reset({ this.depositForm.reset({
holderType: 'CORP', holderType: 'CORP',
uscibMember: 'N', uscibMember: 'No',
specialCountry: '', specialCountry: '',
}); });
} }

View File

@ -40,7 +40,7 @@
<!-- Title Column --> <!-- Title Column -->
<ng-container matColumnDef="title"> <ng-container matColumnDef="title">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Title</th> <th mat-header-cell *matHeaderCellDef mat-sort-header>Title</th>
<td mat-cell *matCellDef="let contact">{{ contact.title }}</td> <td mat-cell *matCellDef="let contact">{{ getContactTitleLabel(contact.title) }}</td>
</ng-container> </ng-container>
<!-- Phone Column --> <!-- Phone Column -->
@ -159,17 +159,16 @@
</div> </div>
<div class="form-row"> <div class="form-row">
<mat-form-field appearance="outline"> <mat-form-field appearance="outline">
<mat-label>Title</mat-label> <mat-label>Title</mat-label>
<input matInput formControlName="title" required> <mat-select formControlName="title" required>
<mat-icon matSuffix>work</mat-icon> <mat-option *ngFor="let contactTitle of contactTitles" [value]="contactTitle.value">
{{ contactTitle.name }}
</mat-option>
</mat-select>
<mat-error *ngIf="contactForm.get('title')?.errors?.['required']"> <mat-error *ngIf="contactForm.get('title')?.errors?.['required']">
Title is required Title is required
</mat-error> </mat-error>
<mat-error *ngIf="contactForm.get('title')?.errors?.['maxlength']">
Maximum 100 characters allowed
</mat-error>
</mat-form-field> </mat-form-field>
</div> </div>

View File

@ -14,8 +14,10 @@ import { UserPreferences } from '../../core/models/user-preference';
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';
import { ContactService } from '../../core/services/service-provider/contact.service'; import { ContactService } from '../../core/services/service-provider/contact.service';
import { finalize } from 'rxjs'; import { finalize, Subject, takeUntil } from 'rxjs';
import { ContactLogin } from '../../core/models/service-provider/contact-login'; import { ContactLogin } from '../../core/models/service-provider/contact-login';
import { CommonService } from '../../core/services/common/common.service';
import { ContactTitle } from '../../core/models/contact-title';
@Component({ @Component({
selector: 'app-contacts', selector: 'app-contacts',
@ -29,7 +31,7 @@ export class ContactsComponent implements OnInit {
set paginator(value: MatPaginator) { set paginator(value: MatPaginator) {
this.dataSource.paginator = value; this.dataSource.paginator = value;
} }
@ViewChild(MatSort) sort!: MatSort; @ViewChild(MatSort) sort!: MatSort;
displayedColumns: string[] = ['firstName', 'middleInitial', 'lastName', 'title', 'phone', 'mobile', 'fax', 'email', 'defaultContact', 'actions']; displayedColumns: string[] = ['firstName', 'middleInitial', 'lastName', 'title', 'phone', 'mobile', 'fax', 'email', 'defaultContact', 'actions'];
@ -42,6 +44,7 @@ export class ContactsComponent implements OnInit {
showForm = false; showForm = false;
showInactiveContacts = false; showInactiveContacts = false;
contacts: Contact[] = []; contacts: Contact[] = [];
contactTitles: ContactTitle[] = [];
contactReadOnlyFields: any = { contactReadOnlyFields: any = {
lastChangedDate: null, lastChangedDate: null,
@ -54,8 +57,11 @@ export class ContactsComponent implements OnInit {
@Input() userPreferences: UserPreferences = {}; @Input() userPreferences: UserPreferences = {};
@Output() hasContacts = new EventEmitter<boolean>(); @Output() hasContacts = new EventEmitter<boolean>();
private destroy$ = new Subject<void>();
private fb = inject(FormBuilder); private fb = inject(FormBuilder);
private contactService = inject(ContactService); private contactService = inject(ContactService);
private commonService = inject(CommonService);
private notificationService = inject(NotificationService); private notificationService = inject(NotificationService);
private errorHandler = inject(ApiErrorHandlerService); private errorHandler = inject(ApiErrorHandlerService);
private dialog = inject(MatDialog); private dialog = inject(MatDialog);
@ -65,7 +71,7 @@ export class ContactsComponent implements OnInit {
firstName: ['', [Validators.required, Validators.maxLength(50)]], firstName: ['', [Validators.required, Validators.maxLength(50)]],
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]],
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}$/)]],
@ -75,9 +81,15 @@ export class ContactsComponent implements OnInit {
} }
ngOnInit(): void { ngOnInit(): void {
this.loadContactTitles();
this.loadContacts(); this.loadContacts();
} }
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}
ngAfterViewInit() { ngAfterViewInit() {
this.dataSource.paginator = this.paginator; this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort; this.dataSource.sort = this.sort;
@ -101,6 +113,19 @@ export class ContactsComponent implements OnInit {
}); });
} }
loadContactTitles(): void {
this.commonService.getContactTitles()
.pipe(takeUntil(this.destroy$))
.subscribe({
next: (contactTitles) => {
this.contactTitles = contactTitles;
},
error: (error) => {
console.error('Failed to load contact titles', error);
}
});
}
toggleShowInactiveContacts(): void { toggleShowInactiveContacts(): void {
this.showInactiveContacts = !this.showInactiveContacts; this.showInactiveContacts = !this.showInactiveContacts;
this.renderContacts(); this.renderContacts();
@ -281,4 +306,9 @@ export class ContactsComponent implements OnInit {
} }
}); });
} }
getContactTitleLabel(value: string): string {
const type = this.contactTitles.find(t => t.value === value);
return type ? type.name : value;
}
} }