feedback updates

This commit is contained in:
Cyril Joseph 2026-01-28 22:20:47 -04:00
parent 19663213be
commit 2be4a0175e
12 changed files with 197 additions and 47 deletions

View File

@ -41,7 +41,7 @@
<mat-step [completed]="stepsCompleted.shipping" [editable]="stepsCompleted.applicationDetail">
<ng-template matStepLabel>Shipping & Payment</ng-template>
<app-shipping (completed)="onShippingSaved($event)" [headerid]="headerid"
[applicationName]="applicationName" [enableSubmitButton]="allSectionsCompleted">
[applicationName]="applicationName" [missingSectionMessage]="missingSectionMessage">
</app-shipping>
</mat-step>

View File

@ -27,7 +27,7 @@ export class AddCarnetComponent {
headerid: number = 0;
applicationName: string = '';
userPreferences: UserPreferences;
allSectionsCompleted: boolean = false;
missingSectionMessage: string = '';
// Track completion of each step
stepsCompleted = {
@ -38,6 +38,9 @@ export class AddCarnetComponent {
shipping: false
};
@ViewChild(HolderComponent, { static: false })
private holderComponent!: HolderComponent;
@ViewChild(ShippingComponent, { static: false })
private shippingComponent!: ShippingComponent;
@ -54,6 +57,8 @@ export class AddCarnetComponent {
this.applicationName = data.applicationName;
this.stepsCompleted.applicationDetail = true;
this.isLinear = false; // Disable linear mode after application detail is created
this.holderComponent.refreshHolder();
}
onHolderSelectionSaved(completed: boolean): void {
@ -83,8 +88,38 @@ export class AddCarnetComponent {
}
isAllSectionsCompleted(): void {
this.allSectionsCompleted = this.stepsCompleted.applicationDetail
let allSectionsCompleted = this.stepsCompleted.applicationDetail
&& this.stepsCompleted.holderSelection && this.stepsCompleted.goodsSection
&& this.stepsCompleted.shipping && this.stepsCompleted.travelPlan;
if (allSectionsCompleted) {
this.missingSectionMessage = '';
}
else {
let message = 'Missing details in: ';
if (!this.stepsCompleted.applicationDetail) {
message += 'Application Name, ';
}
if (!this.stepsCompleted.holderSelection) {
message += 'Holder Selection, ';
}
if (!this.stepsCompleted.goodsSection) {
message += 'Goods Section, ';
}
if (!this.stepsCompleted.travelPlan) {
message += 'Travel Plan, ';
}
if (!this.stepsCompleted.shipping) {
message += 'Shipping & Payment, ';
}
// Remove trailing comma and space
this.missingSectionMessage = message.replace(/, $/, '');
}
}
}

View File

@ -51,7 +51,7 @@
<ng-template matStepLabel>Shipping & Payment</ng-template>
<app-shipping (completed)="onShippingSaved($event)" [headerid]="headerid" [isEditMode]="isEditMode"
[applicationType]="applicationType" [applicationName]="applicationName"
[enableSubmitButton]="allSectionsCompleted">
[missingSectionMessage]="missingSectionMessage">
</app-shipping>
</mat-step>

View File

@ -28,7 +28,8 @@ export class EditCarnetComponent {
headerid: number = 0;
userPreferences: UserPreferences;
applicationName: string = '';
allSectionsCompleted: boolean = false;
missingSectionMessage: string = '';
@ViewChild(ShippingComponent, { static: false })
private shippingComponent!: ShippingComponent;
@ -125,9 +126,43 @@ export class EditCarnetComponent {
}
isAllSectionsCompleted() {
this.allSectionsCompleted = this.stepsCompleted.applicationDetail
let allSectionsCompleted = this.stepsCompleted.applicationDetail
&& this.stepsCompleted.holderSelection && this.stepsCompleted.goodsSection
&& this.stepsCompleted.shipping && this.stepsCompleted.travelPlan
&& (this.applicationType !== 'extend' || this.stepsCompleted.extension);
if (allSectionsCompleted) {
this.missingSectionMessage = '';
}
else {
let message = 'Missing details in: ';
if(this.applicationType === 'extend' && !this.stepsCompleted.extension) {
message += 'Extension Application, ';
}
if (!this.stepsCompleted.applicationDetail) {
message += 'Application Name, ';
}
if (!this.stepsCompleted.holderSelection) {
message += 'Holder Selection, ';
}
if (!this.stepsCompleted.goodsSection) {
message += 'Goods Section, ';
}
if (!this.stepsCompleted.travelPlan) {
message += 'Travel Plan, ';
}
if (!this.stepsCompleted.shipping) {
message += 'Shipping & Payment, ';
}
// Remove trailing comma and space
this.missingSectionMessage = message.replace(/, $/, '');
}
}
}

View File

@ -21,7 +21,7 @@ export class HolderComponent {
@Output() completed = new EventEmitter<boolean>();
@Output() updated = new EventEmitter<boolean>();
selectedHolderId: number = 0;
selectedHolderId: number | undefined = 0;
private holdersService = inject(HolderService);
private notificationService = inject(NotificationService);
@ -45,6 +45,10 @@ export class HolderComponent {
}
}
public refreshHolder(): void {
this.selectedHolderId = undefined;
}
onHolderSelectionSaved(completed: boolean): void {
this.completed.emit(completed);
this.updated.emit(true); // to update dependent data

View File

@ -343,29 +343,36 @@
</div>
<div class="form-actions">
<button mat-raised-button color="primary" type="button" (click)="showEstimatedFees()"
*ngIf="showEstimatedFeesButton && !isViewMode">
<span>Estimated Fees</span>
</button>
<div class="error-message">
<mat-icon *ngIf="missingSectionMessage">error</mat-icon>
<span *ngIf="missingSectionMessage">{{ missingSectionMessage }}</span>
</div>
<button mat-raised-button color="primary" type="submit" *ngIf="!isViewMode"
[disabled]="shippingForm.invalid || changeInProgress">
Save
</button>
<div class="action-buttons">
<button mat-raised-button color="primary" type="button" (click)="showEstimatedFees()"
*ngIf="showEstimatedFeesButton && !isViewMode">
<span>Estimated Fees</span>
</button>
<button mat-raised-button color="primary" type="button" (click)="processApplication()"
[disabled]="!enableSubmitButton" *ngIf="showProcessButton && !isViewMode">
<span>Process Application</span>
</button>
<button mat-raised-button color="primary" type="submit" *ngIf="!isViewMode"
[disabled]="shippingForm.invalid || changeInProgress">
Save
</button>
<button mat-raised-button color="primary" type="button" (click)="submitApplication()"
[disabled]="!enableSubmitButton" *ngIf="showSubmitButton && !isViewMode">
<span>Submit Application</span>
</button>
<button mat-raised-button color="primary" type="button" (click)="processApplication()"
[disabled]="!enableSubmitButton" *ngIf="showProcessButton && !isViewMode">
<span>Process Application</span>
</button>
<button mat-raised-button color="primary" type="button" (click)="returnToHome()" *ngIf="isViewMode">
Back
</button>
<button mat-raised-button color="primary" type="button" (click)="submitApplication()"
[disabled]="!enableSubmitButton" *ngIf="showSubmitButton && !isViewMode">
<span>Submit Application</span>
</button>
<button mat-raised-button color="primary" type="button" (click)="returnToHome()" *ngIf="isViewMode">
Back
</button>
</div>
</div>
</form>
</div>

View File

@ -63,9 +63,32 @@
.form-actions {
display: flex;
justify-content: flex-end;
justify-content: space-between;
align-items: center;
gap: 16px;
margin-top: 0.9rem;
.error-message {
display: flex;
align-items: center;
color: var(--mat-form-field-error-text-color, var(--mat-sys-error));
-webkit-font-smoothing: antialiased;
font-family: var(--mat-form-field-subscript-text-font, var(--mat-sys-body-small-font));
line-height: var(--mat-form-field-subscript-text-line-height, var(--mat-sys-body-small-line-height));
font-size: var(--mat-form-field-subscript-text-size, var(--mat-sys-body-small-size));
letter-spacing: var(--mat-form-field-subscript-text-tracking, var(--mat-sys-body-small-tracking));
font-weight: var(--mat-form-field-subscript-text-weight, var(--mat-sys-body-small-weight));
mat-icon {
margin-right: 4px;
}
}
.action-buttons {
display: flex;
align-items: center;
gap: 16px;
}
}
.presaved-address {

View File

@ -1,5 +1,5 @@
import { CommonModule } from '@angular/common';
import { Component, EventEmitter, inject, Input, Output } from '@angular/core';
import { Component, EventEmitter, inject, Input, Output, SimpleChanges } from '@angular/core';
import { ReactiveFormsModule, FormBuilder, FormGroup, Validators } from '@angular/forms';
import { NotificationService } from '../../core/services/common/notification.service';
import { AngularMaterialModule } from '../../shared/module/angular-material.module';
@ -38,7 +38,7 @@ export class ShippingComponent {
@Input() headerid: number = 0;
@Input() isEditMode = false;
@Input() isViewMode = false;
@Input() enableSubmitButton = false;
@Input() missingSectionMessage = '';
@Input() applicationName: string = '';
@Input() applicationType: 'new' | 'edit' | 'additional' | 'duplicate' | 'extend' | null = 'edit';
@ -62,6 +62,7 @@ export class ShippingComponent {
showAddressForm = false;
showContactForm = false;
deliveryEstimate: string = '';
enableSubmitButton: boolean = false;
needsInsurance = true;
holderid: number = 0;
holder: Holder | undefined | null = null;
@ -142,6 +143,12 @@ export class ShippingComponent {
}
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['missingSectionMessage']) {
this.enableSubmitButton = this.missingSectionMessage === '';
}
}
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
@ -426,7 +433,7 @@ export class ShippingComponent {
).subscribe({
next: (results) => {
if (!results && !this.shippingFromDB) { // do nothing if empty
if (!results || !this.shippingFromDB) { // do nothing if empty
return;
}

View File

@ -80,12 +80,15 @@ export class SearchHolderComponent {
});
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['selectedHolderId']) {
if (this.selectedHolderId) {
this.showSelectedHolder(this.selectedHolderId);
}
if (this.selectedHolderId === undefined) {
this.autoSelectHolder();
}
}
if (changes['isViewMode'] && this.isViewMode) {
@ -93,6 +96,30 @@ export class SearchHolderComponent {
}
}
// If only one holder is returned, auto select it
autoSelectHolder(): void {
this.isLoading = true;
const filterData: HolderFilter = {};
this.holderService.getHolders(filterData).pipe(finalize(() => {
this.isLoading = false;
})).subscribe({
next: (holders: BasicDetail[]) => {
if (holders && holders.length === 1) {
this.selectedHolderId = holders[0].holderid!;
this.saveHolderSelection();
this.showSelectedHolder(this.selectedHolderId);
}
},
error: (error: any) => {
let errorMessage = this.errorHandler.handleApiError(error, 'Failed to get holders');
this.notificationService.showError(errorMessage);
console.error('Error loading holders:', error);
}
});
}
onSearch(): void {
this.searchHolders();
}

View File

@ -12,41 +12,51 @@
<div class="question-row">
<mat-radio-group (change)="newCarnet($event)">
<mat-label class="question">Do you need a new carnet?</mat-label>
<mat-radio-button [value]="true">Yes</mat-radio-button>
<mat-radio-button [value]="false">No</mat-radio-button>
<div class="answers">
<mat-radio-button [value]="true">Yes</mat-radio-button>
<mat-radio-button [value]="false">No</mat-radio-button>
</div>
</mat-radio-group>
</div>
<div class="question-row">
<mat-radio-group (change)="additionalSets($event)">
<mat-label class="question">Do you need additional sets?</mat-label>
<mat-radio-button [value]="true">Yes</mat-radio-button>
<mat-radio-button [value]="false">No</mat-radio-button>
<div class="answers">
<mat-radio-button [value]="true">Yes</mat-radio-button>
<mat-radio-button [value]="false">No</mat-radio-button>
</div>
</mat-radio-group>
</div>
<div class="question-row">
<mat-radio-group (change)="toggleDuplicateQuestion($event)">
<mat-label class="question">Did you misplace your carnet?</mat-label>
<mat-radio-button [value]="true">Yes</mat-radio-button>
<mat-radio-button [value]="false">No</mat-radio-button>
<div class="answers">
<mat-radio-button [value]="true">Yes</mat-radio-button>
<mat-radio-button [value]="false">No</mat-radio-button>
</div>
</mat-radio-group>
</div>
<div class="question-row" *ngIf="duplicateQuestion">
<mat-radio-group (change)="duplicateCarnet($event)">
<mat-label class="question">Are you looking for
<mat-label class="question sub-question">Are you looking for
duplicates?</mat-label>
<mat-radio-button [value]="true">Yes</mat-radio-button>
<mat-radio-button [value]="false">No</mat-radio-button>
<div class="answers">
<mat-radio-button [value]="true">Yes</mat-radio-button>
<mat-radio-button [value]="false">No</mat-radio-button>
</div>
</mat-radio-group>
</div>
<div class="question-row">
<mat-radio-group (change)="extendCarnet($event)">
<mat-label class="question">Do you need to extend the carnet?</mat-label>
<mat-radio-button [value]="true">Yes</mat-radio-button>
<mat-radio-button [value]="false">No</mat-radio-button>
<div class="answers">
<mat-radio-button [value]="true">Yes</mat-radio-button>
<mat-radio-button [value]="false">No</mat-radio-button>
</div>
</mat-radio-group>
</div>
</div>

View File

@ -33,7 +33,9 @@
mat-radio-group {
display: flex;
gap: 8px;
justify-content: space-between;
align-items: center;
width: 51%;
.question {
color: var(--mat-sys-on-surface);
@ -44,8 +46,8 @@
font-weight: var(--mat-sys-medium-font-weight);
}
mat-radio-button {
margin-top: -5px;
.sub-question {
padding-left: 1.5em;
}
}
}

View File

@ -438,8 +438,8 @@ export class HomeComponent {
next: (applicationData: any) => {
this.notificationService.showSuccess('Carnet copied successfully');
let route: string = this.editActionRoute(item);
this.navigateTo([route, data.headerid], {
queryParams: { applicationname: data.applicationName }
this.navigateTo([route, applicationData.HEADERID], {
queryParams: { applicationname: applicationData.APPLICATIONNAME }
});
},
error: (error) => {