Skip to content

Commit 89bb729

Browse files
authored
2447 Responsible Parties Tab QA (#2593)
* fix: addressed qa changes after time away, more details in PR comment * chore: fixed failing test
1 parent 2dce133 commit 89bb729

File tree

10 files changed

+290
-121
lines changed

10 files changed

+290
-121
lines changed

alcs-frontend/src/app/features/compliance-and-enforcement/compliance-and-enforcement.component.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import { Component, OnDestroy, OnInit } from '@angular/core';
22
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
33
import { Subject, takeUntil } from 'rxjs';
4-
import { detailsRoutes } from './compliance-and-enforcement.module';
54
import { ComplianceAndEnforcementDto } from '../../services/compliance-and-enforcement/compliance-and-enforcement.dto';
65
import {
76
ComplianceAndEnforcementService,
87
FetchOptions,
98
} from '../../services/compliance-and-enforcement/compliance-and-enforcement.service';
10-
import { ToastService } from '../../services/toast/toast.service';
11-
import { ResponsiblePartiesService } from '../../services/compliance-and-enforcement/responsible-parties/responsible-parties.service';
129
import { ResponsiblePartyType } from '../../services/compliance-and-enforcement/responsible-parties/responsible-parties.dto';
10+
import { ResponsiblePartiesService } from '../../services/compliance-and-enforcement/responsible-parties/responsible-parties.service';
11+
import { ToastService } from '../../services/toast/toast.service';
12+
import { detailsRoutes } from './compliance-and-enforcement.module';
1313

1414
@Component({
1515
selector: 'app-compliance-and-enforcement',
@@ -69,8 +69,9 @@ export class ComplianceAndEnforcementComponent implements OnInit, OnDestroy {
6969
ResponsiblePartyType.PROPERTY_OWNER,
7070
);
7171

72-
this.propertyOwnerName =
73-
(owners?.[0].organizationName || owners?.[0].individualName) + (owners.length > 1 ? ' et al.' : '');
72+
this.propertyOwnerName = owners && owners.length > 0
73+
? (owners[0].organizationName || owners[0].individualName) + (owners.length > 1 ? ' et al.' : '')
74+
: '';
7475
}
7576
} catch (error) {
7677
console.error('Error loading file:', error);

alcs-frontend/src/app/features/compliance-and-enforcement/compliance-and-enforcement.module.ts

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
1+
import { CommonModule } from '@angular/common';
12
import { NgModule } from '@angular/core';
3+
import { MatMomentDateModule } from '@angular/material-moment-adapter';
24
import { Route, RouterModule, Routes } from '@angular/router';
35
import { SharedModule } from '../../shared/shared.module';
4-
import { OverviewComponent } from './overview/overview.component';
5-
import { MatMomentDateModule } from '@angular/material-moment-adapter';
6-
import { DraftComponent } from './draft/draft.component';
7-
import { SubmitterComponent } from './submitter/submitter.component';
8-
import { PropertyComponent } from './property/property.component';
9-
import { ComplianceAndEnforcementDocumentsComponent } from './documents/documents.component';
10-
import { ResponsiblePartiesComponent } from './responsible-parties/responsible-parties.component';
11-
import { DetailsOverviewComponent } from './details/overview/details-overview.component';
126
import { ComplianceAndEnforcementComponent } from './compliance-and-enforcement.component';
13-
import { CommonModule } from '@angular/common';
14-
import { DetailsHeaderComponent } from './details/header/details-header.component';
157
import { ComplaintReferralComponent } from './details/complaint-referral/complaint-referral.component';
168
import { ComplaintReferralOverviewComponent } from './details/complaint-referral/overview/overview.component';
17-
import { ComplaintReferralSubmittersComponent } from './details/complaint-referral/submitters/submitters.component';
189
import { AddSubmitterDialogComponent } from './details/complaint-referral/submitters/add-submitter-dialog/add-submitter-dialog.component';
10+
import { ComplaintReferralSubmittersComponent } from './details/complaint-referral/submitters/submitters.component';
11+
import { DetailsHeaderComponent } from './details/header/details-header.component';
12+
import { DetailsOverviewComponent } from './details/overview/details-overview.component';
1913
import { PropertyMapsComponent } from './details/property-maps/property-maps.component';
2014
import { ResponsiblePartiesDetailsComponent } from './details/responsible-parties/responsible-parties.component';
15+
import { ComplianceAndEnforcementDocumentsComponent } from './documents/documents.component';
16+
import { DraftComponent } from './draft/draft.component';
17+
import { OverviewComponent } from './overview/overview.component';
18+
import { PropertyComponent } from './property/property.component';
19+
import { ResponsiblePartiesComponent } from './responsible-parties/responsible-parties.component';
20+
import { SubmitterComponent } from './submitter/submitter.component';
2121

2222
export const detailsRoutes: (Route & { icon?: string; menuTitle?: string })[] = [
2323
{
@@ -49,36 +49,36 @@ export const detailsRoutes: (Route & { icon?: string; menuTitle?: string })[] =
4949
],
5050
},
5151
{
52-
path: 'property-maps',
53-
icon: 'location_on',
54-
menuTitle: 'Property & Maps',
52+
path: 'responsible-parties',
53+
icon: 'people',
54+
menuTitle: 'Owner and Contacts',
5555
children: [
5656
{
5757
path: '',
58-
component: PropertyMapsComponent,
58+
component: ResponsiblePartiesDetailsComponent,
5959
data: { editing: null },
6060
},
6161
{
6262
path: 'edit',
63-
component: PropertyMapsComponent,
64-
data: { editing: 'property' },
63+
component: ResponsiblePartiesDetailsComponent,
64+
data: { editing: 'parties' },
6565
},
6666
],
6767
},
6868
{
69-
path: 'responsible-parties',
70-
icon: 'people',
71-
menuTitle: 'Responsible Parties',
69+
path: 'property-maps',
70+
icon: 'location_on',
71+
menuTitle: 'Property & Maps',
7272
children: [
7373
{
7474
path: '',
75-
component: ResponsiblePartiesDetailsComponent,
75+
component: PropertyMapsComponent,
7676
data: { editing: null },
7777
},
7878
{
7979
path: 'edit',
80-
component: ResponsiblePartiesDetailsComponent,
81-
data: { editing: 'parties' },
80+
component: PropertyMapsComponent,
81+
data: { editing: 'property' },
8282
},
8383
],
8484
},

alcs-frontend/src/app/features/compliance-and-enforcement/details/property-maps/property-maps.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ export class PropertyMapsComponent implements OnInit, OnDestroy {
138138
await this.service.loadFile(this.fileNumber, { withProperty: true });
139139
}
140140

141-
this.router.navigate(['../..'], { relativeTo: this.route });
141+
this.router.navigate(['..'], { relativeTo: this.route });
142142
} catch (error) {
143143
console.error('Error updating property:', error);
144144
this.toastService.showErrorToast('Error updating property');

alcs-frontend/src/app/features/compliance-and-enforcement/details/responsible-parties/responsible-parties.component.html

Lines changed: 89 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
1+
<!-- Header Section when editing -->
2+
<div *ngIf="editing === 'parties'" class="header-section">
3+
<h2>Owner & Contacts > Edit {{ getHeaderPartyType() }}</h2>
4+
</div>
5+
16
<ng-container *ngIf="editing === null">
27
<!-- Responsible Parties View -->
38
<section class="file-section">
4-
<h3>Allegedly Responsible Parties</h3>
9+
<h3 *ngIf="responsibleParties.length === 1">{{ responsibleParties[0].partyType }}</h3>
10+
<h3 *ngIf="responsibleParties.length > 1">Responsible Parties</h3>
511

612
<!-- Crown Party (if property is Crown) -->
713
<div *ngIf="isPropertyCrown" class="party-card">
@@ -31,58 +37,105 @@ <h4>Crown</h4>
3137
<div class="party-header">
3238
<h4>{{ getPartyDisplayName(party) }}</h4>
3339
<div class="party-type-badge" [class.previous]="party.isPrevious">
34-
{{ getPartyTypeDisplay(party) }}
40+
<span *ngIf="party.partyType === ResponsiblePartyType.PROPERTY_OWNER && party.ownerSince && !party.isPrevious" class="owner-since-label">Owner Since: </span>
41+
<span *ngIf="party.partyType === ResponsiblePartyType.PROPERTY_OWNER && party.ownerSince && !party.isPrevious">{{ formatOwnerSince(party.ownerSince) }}</span>
42+
<span *ngIf="!(party.partyType === ResponsiblePartyType.PROPERTY_OWNER && party.ownerSince && !party.isPrevious)">{{ getPartyTypeDisplay(party) }}</span>
3543
</div>
3644
</div>
3745

3846
<div class="party-details">
39-
<!-- Address (if individual) -->
40-
<div *ngIf="party.foippaCategory === FOIPPACategory.INDIVIDUAL && getPartyAddress(party)" class="field">
41-
<div class="field-heading">Mailing Address</div>
42-
<div>{{ getPartyAddress(party) }}</div>
43-
</div>
47+
<!-- Contact Information Row (3-column layout) - Only for individuals -->
48+
<div *ngIf="party.foippaCategory === FOIPPACategory.INDIVIDUAL" class="contact-row">
49+
<!-- Address (if individual) -->
50+
<div *ngIf="getPartyAddress(party)" class="field">
51+
<div class="field-heading">Mailing Address</div>
52+
<div>{{ getPartyAddress(party) }}</div>
53+
</div>
54+
55+
<!-- Empty div for spacing if no address -->
56+
<div *ngIf="!getPartyAddress(party)" class="field">
57+
</div>
4458

45-
<!-- Email -->
46-
<div class="field">
47-
<div class="field-heading">Email</div>
48-
<app-inline-text
49-
[value]="getPartyEmail(party)"
50-
[isEmail]="true"
51-
addText="Add Email"
52-
placeholder="Add Email"
53-
(save)="saveInlineEdit(party, 'email', $event)"
54-
></app-inline-text>
59+
<!-- Email -->
60+
<div class="field">
61+
<div class="field-heading">Email</div>
62+
<app-inline-text
63+
[value]="getPartyEmail(party)"
64+
[isEmail]="true"
65+
addText="Add Email"
66+
placeholder="Add Email"
67+
(save)="saveInlineEdit(party, 'email', $event)"
68+
></app-inline-text>
69+
</div>
70+
71+
<!-- Telephone -->
72+
<div class="field">
73+
<div class="field-heading">Telephone</div>
74+
<app-inline-text
75+
[value]="getPartyPhone(party)"
76+
[mask]="'(000) 000-0000'"
77+
addText="Add Telephone"
78+
placeholder="Add Telephone"
79+
(save)="saveInlineEdit(party, 'phone', $event)"
80+
></app-inline-text>
81+
</div>
5582
</div>
5683

57-
<!-- Telephone -->
58-
<div class="field">
59-
<div class="field-heading">Telephone</div>
84+
<!-- Notes (for organizations, show under org name) -->
85+
<div *ngIf="party.foippaCategory === FOIPPACategory.ORGANIZATION" class="field">
86+
<div class="field-heading">Note</div>
6087
<app-inline-text
61-
[value]="getPartyPhone(party)"
62-
[mask]="'(000) 000-0000'"
63-
addText="Add Telephone"
64-
placeholder="Add Telephone"
65-
(save)="saveInlineEdit(party, 'phone', $event)"
88+
[value]="getPartyNotes(party)"
89+
addText="Add Notes"
90+
placeholder="Add Notes"
91+
(save)="saveInlineEdit(party, 'notes', $event)"
6692
></app-inline-text>
6793
</div>
68-
6994
<!-- Directors (if organization) -->
7095
<div *ngIf="party.foippaCategory === FOIPPACategory.ORGANIZATION && party.directors?.length" class="directors-section">
71-
<div class="field-heading">Directors</div>
72-
<div *ngFor="let director of party.directors" class="director-item">
73-
<div class="director-name">{{ director.directorName }}</div>
74-
<div class="director-details">
75-
<div *ngIf="director.directorMailingAddress">{{ director.directorMailingAddress }}</div>
76-
<div *ngIf="director.directorEmail">
77-
<a [href]="'mailto:' + director.directorEmail">{{ director.directorEmail }}</a>
96+
<div *ngFor="let director of party.directors; let i = index" class="director-container">
97+
<!-- Director Name Row -->
98+
<div class="director-name-row">
99+
<strong>Director: {{ director.directorName }}</strong>
100+
</div>
101+
102+
<!-- Director Contact Row (3-column layout) -->
103+
<div class="contact-row">
104+
<div class="field">
105+
<div class="field-heading">Mailing Address</div>
106+
<div *ngIf="director.directorMailingAddress; else noAddress">{{ director.directorMailingAddress }}</div>
107+
<ng-template #noAddress>-</ng-template>
108+
</div>
109+
110+
<div class="field">
111+
<div class="field-heading">Email</div>
112+
<app-inline-text
113+
[value]="director.directorEmail || ''"
114+
[isEmail]="true"
115+
addText="Add Email"
116+
placeholder="Add Email"
117+
(save)="saveDirectorInlineEdit(party, director, 'email', $event)"
118+
></app-inline-text>
119+
</div>
120+
121+
<div class="field">
122+
<div class="field-heading">Telephone</div>
123+
<app-inline-text
124+
[value]="director.directorTelephone || ''"
125+
[mask]="'(000) 000-0000'"
126+
addText="Add Telephone"
127+
placeholder="Add Telephone"
128+
(save)="saveDirectorInlineEdit(party, director, 'phone', $event)"
129+
></app-inline-text>
78130
</div>
79-
<div *ngIf="director.directorTelephone">{{ director.directorTelephone | mask: "(000) 000-0000" }}</div>
80131
</div>
132+
133+
<hr *ngIf="i < (party.directors?.length || 0) - 1" class="director-separator">
81134
</div>
82135
</div>
83136

84-
<!-- Notes -->
85-
<div class="field">
137+
<!-- Notes (for individuals only, since organizations have it above) -->
138+
<div *ngIf="party.foippaCategory === FOIPPACategory.INDIVIDUAL" class="field">
86139
<div class="field-heading">Notes</div>
87140
<app-inline-text
88141
[value]="getPartyNotes(party)"
@@ -116,7 +169,6 @@ <h4>{{ getPartyDisplayName(party) }}</h4>
116169
<ng-container *ngIf="editing === 'parties'">
117170
<form [formGroup]="form">
118171
<section class="form-section">
119-
<h3>Responsible Parties > Edit Allegedly Responsible Parties</h3>
120172
<app-compliance-and-enforcement-responsible-parties
121173
#responsiblePartiesComponent
122174
[fileUuid]="file?.uuid"

alcs-frontend/src/app/features/compliance-and-enforcement/details/responsible-parties/responsible-parties.component.scss

Lines changed: 45 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
@use '../../../../../styles/colors';
22

3+
.header-section {
4+
margin-bottom: 24px;
5+
6+
h2 {
7+
margin: 0;
8+
font-size: 24px;
9+
font-weight: 600;
10+
}
11+
}
12+
313
h5 {
414
margin: 16px 0 !important;
515
}
@@ -84,22 +94,27 @@ a[mat-stroked-button] {
8494
}
8595

8696
.party-type-badge {
87-
background-color: colors.$primary-color-light;
88-
color: colors.$primary-color;
89-
padding: 4px 12px;
90-
border-radius: 16px;
9197
font-size: 14px;
9298
font-weight: 500;
9399

94100
&.previous {
95-
background-color: colors.$grey;
96-
color: colors.$dark-contrast-text;
101+
color: colors.$grey-dark;
102+
}
103+
104+
.owner-since-label {
105+
font-weight: bold;
97106
}
98107
}
99108

100109
.party-details {
110+
display: flex;
111+
flex-direction: column;
112+
gap: 16px;
113+
}
114+
115+
.contact-row {
101116
display: grid;
102-
grid-template-columns: 1fr 1fr;
117+
grid-template-columns: 1fr 1fr 1fr;
103118
gap: 16px;
104119
}
105120

@@ -176,29 +191,36 @@ a[mat-stroked-button] {
176191
}
177192

178193
.directors-section {
179-
grid-column: span 2;
180194
margin-top: 8px;
181195
}
182196

183-
.director-item {
184-
background-color: white;
185-
padding: 12px;
186-
border-radius: 4px;
187-
margin-bottom: 8px;
188-
189-
.director-name {
190-
font-weight: 600;
191-
margin-bottom: 4px;
192-
}
197+
.director-container {
198+
padding: 12px 0;
199+
display: flex;
200+
flex-direction: column;
201+
gap: 8px;
193202

194-
.director-details {
195-
font-size: 14px;
196-
color: colors.$grey-dark;
203+
.director-name-row {
204+
margin-bottom: 8px;
197205

198-
div {
199-
margin-bottom: 2px;
206+
strong {
207+
font-weight: 600;
208+
font-size: 16px;
200209
}
201210
}
211+
212+
.contact-row {
213+
display: grid;
214+
grid-template-columns: 1fr 1fr 1fr;
215+
gap: 16px;
216+
}
217+
218+
.director-separator {
219+
border: none;
220+
border-top: 1px solid colors.$grey-dark;
221+
margin: 24px 0 8px 0;
222+
width: 100%;
223+
}
202224
}
203225

204226
a {

0 commit comments

Comments
 (0)