Skip to content

Commit

Permalink
Merge pull request #943 from bcgov/feature/ALCS-1033
Browse files Browse the repository at this point in the history
Add Transferees UI
  • Loading branch information
dhaselhan authored Sep 6, 2023
2 parents a147132 + ff74bed commit badabdd
Show file tree
Hide file tree
Showing 15 changed files with 584 additions and 172 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<ng-template #header>
<div class="header">
<h6 *ngIf="notificationSubmission">Notice of Intent ID: {{ notificationSubmission.fileNumber }} | {{ notificationSubmission.type }}</h6>
<h6 *ngIf="notificationSubmission">
Notification ID: {{ notificationSubmission.fileNumber }} | {{ notificationSubmission.type }}
</h6>
<div class="header-btn-wrapper">
<button
*ngIf="notificationSubmission?.fileNumber && cdkStepper.selectedIndex === steps.ReviewAndSubmit"
Expand All @@ -10,15 +12,6 @@ <h6 *ngIf="notificationSubmission">Notice of Intent ID: {{ notificationSubmissio
>
Download PDF
</button>
<div class="change-app-type-btn-wrapper">
<button mat-flat-button color="accent" (click)="onChangeSubmissionType()">Change SRW Type</button>
<mat-icon
color="accent"
matTooltip="Changing application type will remove some inputs from your saved progress"
>
help_outline
</mat-icon>
</div>
</div>
</div>
</ng-template>
Expand All @@ -33,17 +26,26 @@ <h6 *ngIf="notificationSubmission">Notice of Intent ID: {{ notificationSubmissio
<ng-container *ngTemplateOutlet="header"></ng-container>
<div *ngIf="cdkStepper.selectedIndex === steps.Parcel">
<app-notification-parcel-details
[$notificationSubmission]='$notificationSubmission'
[$notificationSubmission]="$notificationSubmission"
[showErrors]="showValidationErrors"
(navigateToStep)="switchStep($event)"
(componentInitialized)="onParcelDetailsInitialized()"
(exit)="onExit()">
(exit)="onExit()"
>
</app-notification-parcel-details>
</div>
</cdk-step>
<cdk-step label="Identify Transferees">
<ng-container *ngTemplateOutlet="header"></ng-container>
<div *ngIf="cdkStepper.selectedIndex === steps.Transferees"></div>
<div *ngIf="cdkStepper.selectedIndex === steps.Transferees">
<app-transferees
[$notificationSubmission]="$notificationSubmission"
[showErrors]="showValidationErrors"
(navigateToStep)="switchStep($event)"
(exit)="onExit()"
>
</app-transferees>
</div>
</cdk-step>
<cdk-step label="Primary Contact">
<ng-container *ngTemplateOutlet="header"></ng-container>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatTableModule } from '@angular/material/table';
import { RouterModule, Routes } from '@angular/router';
import { NgxMaskPipe } from 'ngx-mask';
import { CanDeactivateGuard } from '../../../shared/guard/can-deactivate.guard';
import { SharedModule } from '../../../shared/shared.module';
import { EditSubmissionComponent } from './edit-submission.component';
Expand All @@ -9,6 +13,8 @@ import { ParcelDetailsComponent } from './parcels/parcel-details.component';
import { ParcelEntryConfirmationDialogComponent } from './parcels/parcel-entry/parcel-entry-confirmation-dialog/parcel-entry-confirmation-dialog.component';
import { ParcelEntryComponent } from './parcels/parcel-entry/parcel-entry.component';
import { StepComponent } from './step.partial';
import { TransfereeDialogComponent } from './transferees/transferee-dialog/transferee-dialog.component';
import { TransfereesComponent } from './transferees/transferees.component';

const routes: Routes = [
{
Expand All @@ -30,7 +36,17 @@ const routes: Routes = [
ParcelEntryComponent,
ParcelEntryConfirmationDialogComponent,
DeleteParcelDialogComponent,
TransfereesComponent,
TransfereeDialogComponent,
],
imports: [
CommonModule,
SharedModule,
RouterModule.forChild(routes),
MatButtonModule,
MatIconModule,
MatTableModule,
NgxMaskPipe,
],
imports: [CommonModule, SharedModule, RouterModule.forChild(routes)],
})
export class EditSubmissionModule {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<div mat-dialog-title>
<h2 *ngIf="!isEdit">Add New Transferee</h2>
<h2 *ngIf="isEdit">Edit Transferee</h2>
</div>
<div mat-dialog-content>
<form [formGroup]="form">
<div class="form-row">
<div class="full-row">
<label for="type">Transferee Type</label>
<mat-button-toggle-group (change)="onChangeType($event)" class="input" id="type" formControlName="type">
<mat-button-toggle [value]="OWNER_TYPE.INDIVIDUAL">Individual</mat-button-toggle>
<mat-button-toggle [value]="OWNER_TYPE.ORGANIZATION">Organization</mat-button-toggle>
</mat-button-toggle-group>
</div>
<div class="full-row" *ngIf="type.getRawValue() === OWNER_TYPE.ORGANIZATION">
<label for="orgName">Organization Name</label>
<mat-form-field appearance="outline">
<input id="orgName" matInput placeholder="Enter Organization Name" formControlName="organizationName" />
</mat-form-field>
<div
*ngIf="organizationName.invalid && (organizationName.dirty || organizationName.touched)"
class="field-error"
>
<mat-icon>warning</mat-icon>
<div *ngIf="organizationName.errors?.['required']">This field is required</div>
</div>
</div>
<h4 class="full-row" *ngIf="type.getRawValue() === OWNER_TYPE.ORGANIZATION">Organization Contact Info</h4>
<div>
<label for="firstName">First Name</label>
<mat-form-field appearance="outline">
<input id="firstName" matInput placeholder="Enter First Name" formControlName="firstName" />
</mat-form-field>
<div *ngIf="firstName.invalid && (firstName.dirty || firstName.touched)" class="field-error">
<mat-icon>warning</mat-icon>
<div *ngIf="firstName.errors?.['required']">This field is required</div>
</div>
</div>
<div>
<label for="lastName">Last Name</label>
<mat-form-field appearance="outline">
<input id="lastName" matInput placeholder="Enter Last Name" formControlName="lastName" />
</mat-form-field>
<div *ngIf="lastName.invalid && (lastName.dirty || lastName.touched)" class="field-error">
<mat-icon>warning</mat-icon>
<div *ngIf="lastName.errors?.['required']">This field is required</div>
</div>
</div>
<div>
<label for="phoneNumber">Phone Number</label>
<mat-form-field appearance="outline">
<input
id="phoneNumber"
mask="(000) 000-0000"
matInput
placeholder="(555) 555-5555"
formControlName="phoneNumber"
/>
</mat-form-field>
<div *ngIf="phoneNumber.invalid && (phoneNumber.dirty || phoneNumber.touched)" class="field-error">
<mat-icon>warning</mat-icon>
<div *ngIf="phoneNumber.errors?.['required']">This field is required</div>
<div *ngIf="phoneNumber.errors?.['mask']">Invalid format</div>
</div>
</div>
<div>
<label for="firstName">Email</label>
<mat-form-field appearance="outline">
<input id="email" type="email" matInput placeholder="Enter Email" formControlName="email" />
</mat-form-field>
<div *ngIf="email.invalid && (email.dirty || email.touched)" class="field-error">
<mat-icon>warning</mat-icon>
<div *ngIf="email.errors?.['required']">This field is required</div>
<div *ngIf="email.errors?.['email']">Invalid format</div>
</div>
</div>
</div>
</form>
</div>
<div mat-dialog-actions class="actions">
<button mat-stroked-button (click)="onClose()">Cancel</button>
<button mat-flat-button color="primary" [disabled]="form.invalid" *ngIf="!isEdit" (click)="onCreate()">Add</button>
<button mat-flat-button color="primary" [disabled]="form.invalid" *ngIf="isEdit" (click)="onSave()">Save</button>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
@use '../../../../../../styles/functions' as *;
@use '../../../../../../styles/colors';

.actions {
button:not(:last-child) {
margin-right: rem(8) !important;
}
}

:host::ng-deep {
.field-error {
color: colors.$error-color;
font-size: rem(15);
font-weight: 700;
display: flex;
align-items: center;
margin-top: rem(4);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog';
import { createMock, DeepMocked } from '@golevelup/ts-jest';
import { NotificationTransfereeService } from '../../../../../services/notification-transferee/notification-transferee.service';

import { TransfereeDialogComponent } from './transferee-dialog.component';

describe('TransfereeDialogComponent', () => {
let component: TransfereeDialogComponent;
let fixture: ComponentFixture<TransfereeDialogComponent>;
let mockTransfereeService: DeepMocked<NotificationTransfereeService>;

beforeEach(async () => {
mockTransfereeService = createMock();

await TestBed.configureTestingModule({
providers: [
{
provide: NotificationTransfereeService,
useValue: mockTransfereeService,
},
{
provide: MatDialogRef,
useValue: {},
},
{
provide: MAT_DIALOG_DATA,
useValue: {},
},
{
provide: MatDialog,
useValue: {},
},
],
declarations: [TransfereeDialogComponent],
schemas: [NO_ERRORS_SCHEMA],
}).compileComponents();

fixture = TestBed.createComponent(TransfereeDialogComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import { Component, Inject } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { MatButtonToggleChange } from '@angular/material/button-toggle';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import {
NotificationTransfereeCreateDto,
NotificationTransfereeDto,
NotificationTransfereeUpdateDto,
} from '../../../../../services/notification-transferee/notification-transferee.dto';
import { NotificationTransfereeService } from '../../../../../services/notification-transferee/notification-transferee.service';
import { OWNER_TYPE } from '../../../../../shared/dto/owner.dto';

@Component({
selector: 'app-transferee-dialog',
templateUrl: './transferee-dialog.component.html',
styleUrls: ['./transferee-dialog.component.scss'],
})
export class TransfereeDialogComponent {
OWNER_TYPE = OWNER_TYPE;
type = new FormControl<string | null>(OWNER_TYPE.INDIVIDUAL);
firstName = new FormControl<string | null>('', [Validators.required]);
lastName = new FormControl<string | null>('', [Validators.required]);
organizationName = new FormControl<string | null>('');
phoneNumber = new FormControl<string | null>('', [Validators.required]);
email = new FormControl<string | null>('', [Validators.required, Validators.email]);

isEdit = false;
existingUuid: string | undefined;

form = new FormGroup({
type: this.type,
firstName: this.firstName,
lastName: this.lastName,
organizationName: this.organizationName,
phoneNumber: this.phoneNumber,
email: this.email,
});

constructor(
private dialogRef: MatDialogRef<TransfereeDialogComponent>,
private transfereeService: NotificationTransfereeService,
@Inject(MAT_DIALOG_DATA)
public data: {
submissionUuid: string;
existingTransferee?: NotificationTransfereeDto;
}
) {
if (data && data.existingTransferee) {
this.onChangeType({
value: data.existingTransferee.type.code,
} as any);
this.isEdit = true;
this.type.setValue(data.existingTransferee.type.code);
this.firstName.setValue(data.existingTransferee.firstName);
this.lastName.setValue(data.existingTransferee.lastName);
this.organizationName.setValue(data.existingTransferee.organizationName);
this.phoneNumber.setValue(data.existingTransferee.phoneNumber);
this.email.setValue(data.existingTransferee.email);
this.existingUuid = data.existingTransferee.uuid;
}
}

onChangeType($event: MatButtonToggleChange) {
if ($event.value === OWNER_TYPE.ORGANIZATION) {
this.organizationName.setValidators([Validators.required]);
} else {
this.organizationName.setValidators([]);
this.organizationName.reset();
}
}

async onCreate() {
if (!this.data.submissionUuid) {
console.error('TransfereeDialogComponent misconfigured, needs submissionUuid for create');
return;
}

const createDto: NotificationTransfereeCreateDto = {
organizationName: this.organizationName.getRawValue() || undefined,
firstName: this.firstName.getRawValue() || undefined,
lastName: this.lastName.getRawValue() || undefined,
email: this.email.getRawValue()!,
phoneNumber: this.phoneNumber.getRawValue()!,
typeCode: this.type.getRawValue()!,
notificationSubmissionUuid: this.data.submissionUuid,
};

await this.transfereeService.create(createDto);
this.dialogRef.close(true);
}

async onClose() {
this.dialogRef.close(false);
}

async onSave() {
const updateDto: NotificationTransfereeUpdateDto = {
organizationName: this.organizationName.getRawValue(),
firstName: this.firstName.getRawValue(),
lastName: this.lastName.getRawValue(),
email: this.email.getRawValue()!,
phoneNumber: this.phoneNumber.getRawValue()!,
typeCode: this.type.getRawValue()!,
};
if (this.existingUuid) {
await this.transfereeService.update(this.existingUuid, updateDto);
this.dialogRef.close(true);
}
}
}
Loading

0 comments on commit badabdd

Please sign in to comment.