Skip to content

Commit d2ca904

Browse files
authored
Merge pull request #2353 from bcgov/bugfix/2266
Fix public/portal document links
2 parents 9ab0811 + 49407b8 commit d2ca904

File tree

188 files changed

+2270
-742
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

188 files changed

+2270
-742
lines changed

alcs-frontend/src/app/shared/document-file-loader/document-file-loader.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { ActivatedRoute } from '@angular/router';
33
import { DocumentService } from '../../services/common/document/document.service';
44

55
@Component({
6-
selector: 'app-temp',
6+
selector: 'document-file-loader',
77
templateUrl: './document-file-loader.component.html',
88
styleUrl: './document-file-loader.component.scss',
99
})

portal-frontend/src/app/features/applications/application-details/application-details.component.html

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,16 @@ <h3>3. Primary Contact</h3>
9191
[showRequired]="showErrors && needsAuthorizationLetter"
9292
></app-no-data>
9393
<div *ngFor="let file of authorizationLetters">
94-
<a routerLink="/document/{{ file.documentUuid }}" target="_blank" data-testid="authorization-letter">{{
94+
<a *ngIf="isMobile" (click)="downloadFile(file.documentUuid)" data-testid="authorization-letter">{{
9595
file.fileName
9696
}}</a>
97+
<a
98+
*ngIf="!isMobile"
99+
routerLink="/document/{{ file.documentUuid }}"
100+
target="_blank"
101+
data-testid="authorization-letter"
102+
>{{ file.fileName }}</a
103+
>
97104
</div>
98105
<app-validation-error *ngIf="!needsAuthorizationLetter && authorizationLetters.length > 0">
99106
Authorization letters are not required, please remove them
@@ -314,16 +321,16 @@ <h3>6. Proposal</h3>
314321
</section>
315322
<section>
316323
<h3>7. Optional Documents</h3>
317-
<div *ngIf="applicationSubmission"
318-
[ngClass]="{'review-table': !isMobile, 'review-list': isMobile}">
324+
<div *ngIf="applicationSubmission" [ngClass]="{ 'review-table': !isMobile, 'review-list': isMobile }">
319325
<div *ngIf="!isMobile" class="other-attachments full-width">
320326
<div class="grid-1 subheading2">File Name</div>
321327
<div class="grid-2 subheading2">Type</div>
322328
<div class="grid-3 subheading2">Description</div>
323329

324330
<ng-container *ngFor="let file of otherFiles">
325331
<div class="grid-1" data-testid="optional-document-file-name">
326-
<a routerLink="/document/{{ file.documentUuid }}" target="_blank">{{ file.fileName }}</a>
332+
<a *ngIf="isMobile" (click)="downloadFile(file.documentUuid)">{{ file.fileName }}</a>
333+
<a *ngIf="!isMobile" routerLink="/document/{{ file.documentUuid }}" target="_blank">{{ file.fileName }}</a>
327334
</div>
328335
<div class="grid-2" data-testid="optional-document-type">
329336
{{ file.type?.label }}

portal-frontend/src/app/features/applications/application-details/application-details.component.spec.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import { ApplicationSubmissionDetailedDto } from '../../../services/application-
1010
import { CodeService } from '../../../services/code/code.service';
1111

1212
import { ApplicationDetailsComponent } from './application-details.component';
13+
import { HttpClient } from '@angular/common/http';
14+
import { DocumentService } from '../../../services/document/document.service';
1315

1416
describe('ApplicationDetailsComponent', () => {
1517
let component: ApplicationDetailsComponent;
@@ -18,6 +20,8 @@ describe('ApplicationDetailsComponent', () => {
1820
let mockAppDocumentService: DeepMocked<ApplicationDocumentService>;
1921
let mockRouter: DeepMocked<Router>;
2022
let mockParcelService: DeepMocked<ApplicationParcelService>;
23+
let mockHttpClient: DeepMocked<HttpClient>;
24+
let mockDocumentService: DeepMocked<DocumentService>;
2125

2226
let applicationDocumentPipe = new BehaviorSubject<ApplicationDocumentDto[]>([]);
2327

@@ -26,6 +30,8 @@ describe('ApplicationDetailsComponent', () => {
2630
mockAppDocumentService = createMock();
2731
mockRouter = createMock();
2832
mockParcelService = createMock();
33+
mockHttpClient = createMock();
34+
mockDocumentService = createMock();
2935

3036
await TestBed.configureTestingModule({
3137
providers: [
@@ -45,6 +51,14 @@ describe('ApplicationDetailsComponent', () => {
4551
provide: ApplicationParcelService,
4652
useValue: mockParcelService,
4753
},
54+
{
55+
provide: HttpClient,
56+
useValue: mockHttpClient,
57+
},
58+
{
59+
provide: DocumentService,
60+
useValue: mockDocumentService,
61+
},
4862
],
4963
declarations: [ApplicationDetailsComponent],
5064
schemas: [NO_ERRORS_SCHEMA],

portal-frontend/src/app/features/applications/application-details/application-details.component.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@ import { LocalGovernmentDto } from '../../../services/code/code.dto';
1313
import { CodeService } from '../../../services/code/code.service';
1414
import { DOCUMENT_SOURCE, DOCUMENT_TYPE } from '../../../shared/dto/document.dto';
1515
import { OWNER_TYPE } from '../../../shared/dto/owner.dto';
16-
import { openFileInline } from '../../../shared/utils/file';
1716
import { MOBILE_BREAKPOINT } from '../../../shared/utils/breakpoints';
17+
import { DocumentService } from '../../../services/document/document.service';
18+
import { downloadFile } from '../../../shared/utils/file';
19+
import { ToastService } from '../../../services/toast/toast.service';
1820

1921
@Component({
2022
selector: 'app-application-details',
@@ -47,7 +49,9 @@ export class ApplicationDetailsComponent implements OnInit, OnDestroy {
4749
private codeService: CodeService,
4850
private applicationDocumentService: ApplicationDocumentService,
4951
private applicationParcelService: ApplicationParcelService,
50-
private router: Router
52+
private router: Router,
53+
private documentService: DocumentService,
54+
private toastService: ToastService,
5155
) {}
5256

5357
ngOnInit(): void {
@@ -85,10 +89,13 @@ export class ApplicationDetailsComponent implements OnInit, OnDestroy {
8589
this.$destroy.complete();
8690
}
8791

88-
async openFile(file: ApplicationDocumentDto) {
89-
const res = await this.applicationDocumentService.openFile(file.uuid);
90-
if (res) {
91-
openFileInline(res.url, file.fileName);
92+
async downloadFile(uuid: string) {
93+
try {
94+
const { url, fileName } = await this.documentService.getDownloadUrlAndFileName(uuid, false, true);
95+
96+
downloadFile(url, fileName);
97+
} catch (e) {
98+
this.toastService.showErrorToast('Failed to download file');
9299
}
93100
}
94101

portal-frontend/src/app/features/applications/application-details/cove-details/cove-details.component.html

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,10 @@
5252

5353
<div class="subheading2 grid-1">Proposal Map / Site Plan</div>
5454
<div class="grid-double">
55-
<a *ngFor="let map of proposalMap" routerLink="/document/{{ map.documentUuid }}" target="_blank">
56-
{{ map.fileName }}
57-
</a>
55+
<ng-container *ngFor="let map of proposalMap">
56+
<a *ngIf="isMobile" (click)="downloadFile(map.documentUuid)">{{ map.fileName }}</a>
57+
<a *ngIf="!isMobile" routerLink="/document/{{ map.documentUuid }}" target="_blank">{{ map.fileName }}</a>
58+
</ng-container>
5859
<app-no-data [showRequired]="showErrors" *ngIf="proposalMap.length === 0"></app-no-data>
5960
</div>
6061

@@ -70,9 +71,8 @@
7071
<div class="subheading2 grid-1">Draft Covenant</div>
7172
<div class="grid-double">
7273
<div *ngFor="let file of srwTerms">
73-
<a routerLink="/document/{{ file.documentUuid }}" target="_blank">
74-
{{ file.fileName }}
75-
</a>
74+
<a *ngIf="isMobile" (click)="downloadFile(file.documentUuid)">{{ file.fileName }}</a>
75+
<a *ngIf="!isMobile" routerLink="/document/{{ file.documentUuid }}" target="_blank">{{ file.fileName }}</a>
7676
</div>
7777
<app-no-data
7878
[showRequired]="showErrors && !!_applicationSubmission.coveHasDraft"

portal-frontend/src/app/features/applications/application-details/cove-details/cove-details.component.spec.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,27 @@
11
import { NO_ERRORS_SCHEMA } from '@angular/core';
22
import { ComponentFixture, TestBed } from '@angular/core/testing';
3-
import { DeepMocked } from '@golevelup/ts-jest';
3+
import { createMock, DeepMocked } from '@golevelup/ts-jest';
44
import { CovenantTransfereeService } from '../../../../services/covenant-transferee/covenant-transferee.service';
55

66
import { CoveDetailsComponent } from './cove-details.component';
77
import { ApplicationDocumentService } from '../../../../services/application-document/application-document.service';
88
import { ApplicationParcelService } from '../../../../services/application-parcel/application-parcel.service';
9+
import { DocumentService } from '../../../../services/document/document.service';
910

1011
describe('CoveDetailsComponent', () => {
1112
let component: CoveDetailsComponent;
1213
let fixture: ComponentFixture<CoveDetailsComponent>;
1314
let mockAppDocumentService: DeepMocked<ApplicationDocumentService>;
1415
let mockAppParcelService: DeepMocked<ApplicationParcelService>;
1516
let mockTransfereeService: DeepMocked<CovenantTransfereeService>;
17+
let mockDocumentService: DeepMocked<DocumentService>;
1618

1719
beforeEach(async () => {
20+
mockAppDocumentService = createMock();
21+
mockAppParcelService = createMock();
22+
mockTransfereeService = createMock();
23+
mockDocumentService = createMock();
24+
1825
await TestBed.configureTestingModule({
1926
declarations: [CoveDetailsComponent],
2027
providers: [
@@ -30,6 +37,10 @@ describe('CoveDetailsComponent', () => {
3037
provide: CovenantTransfereeService,
3138
useValue: mockTransfereeService,
3239
},
40+
{
41+
provide: DocumentService,
42+
useValue: mockDocumentService,
43+
},
3344
],
3445
schemas: [NO_ERRORS_SCHEMA],
3546
}).compileComponents();

portal-frontend/src/app/features/applications/application-details/cove-details/cove-details.component.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import { Component, HostListener, Input } from '@angular/core';
22
import { Router } from '@angular/router';
33
import { ApplicationDocumentDto } from '../../../../services/application-document/application-document.dto';
4-
import { ApplicationDocumentService } from '../../../../services/application-document/application-document.service';
54
import { ApplicationSubmissionDetailedDto } from '../../../../services/application-submission/application-submission.dto';
65
import { CovenantTransfereeDto } from '../../../../services/covenant-transferee/covenant-transferee.dto';
76
import { CovenantTransfereeService } from '../../../../services/covenant-transferee/covenant-transferee.service';
87
import { DOCUMENT_TYPE } from '../../../../shared/dto/document.dto';
9-
import { openFileInline } from '../../../../shared/utils/file';
108
import { MOBILE_BREAKPOINT } from '../../../../shared/utils/breakpoints';
9+
import { DocumentService } from '../../../../services/document/document.service';
10+
import { downloadFile } from '../../../../shared/utils/file';
11+
import { ToastService } from '../../../../services/toast/toast.service';
1112

1213
@Component({
1314
selector: 'app-cove-details',
@@ -41,8 +42,9 @@ export class CoveDetailsComponent {
4142

4243
constructor(
4344
private router: Router,
44-
private applicationDocumentService: ApplicationDocumentService,
4545
private covenantTransfereeService: CovenantTransfereeService,
46+
private documentService: DocumentService,
47+
private toastService: ToastService,
4648
) {}
4749

4850
async onEditSection(step: number) {
@@ -55,10 +57,13 @@ export class CoveDetailsComponent {
5557
}
5658
}
5759

58-
async openFile(file: ApplicationDocumentDto) {
59-
const res = await this.applicationDocumentService.openFile(file.uuid);
60-
if (res) {
61-
openFileInline(res.url, file.fileName);
60+
async downloadFile(uuid: string) {
61+
try {
62+
const { url, fileName } = await this.documentService.getDownloadUrlAndFileName(uuid, false, true);
63+
64+
downloadFile(url, fileName);
65+
} catch (e) {
66+
this.toastService.showErrorToast('Failed to download file');
6267
}
6368
}
6469

portal-frontend/src/app/features/applications/application-details/excl-details/excl-details.component.html

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,38 +37,36 @@
3737

3838
<div class="subheading2 grid-1">Proposal Map / Site Plan</div>
3939
<div class="grid-double">
40-
<a *ngFor="let map of proposalMap" routerLink="/document/{{ map.documentUuid }}" target="_blank">
41-
{{ map.fileName }}
42-
</a>
40+
<ng-container *ngFor="let map of proposalMap">
41+
<a class="mobile" (click)="downloadFile(map.documentUuid)">{{ map.fileName }}</a>
42+
<a class="desktop" routerLink="/document/{{ map.documentUuid }}" target="_blank">{{ map.fileName }}</a>
43+
</ng-container>
4344
<app-no-data [showRequired]="showErrors" *ngIf="proposalMap.length === 0"></app-no-data>
4445
</div>
4546

4647
<div class="subheading2 grid-1">Notice of Public Hearing (Advertisement)</div>
4748
<div class="grid-double">
4849
<div *ngFor="let file of noticeOfPublicHearing">
49-
<a routerLink="/document/{{ file.documentUuid }}" target="_blank">
50-
{{ file.fileName }}
51-
</a>
50+
<a class="mobile" (click)="downloadFile(file.documentUuid)">{{ file.fileName }}</a>
51+
<a class="desktop" routerLink="/document/{{ file.documentUuid }}" target="_blank">{{ file.fileName }}</a>
5252
</div>
5353
<app-no-data [showRequired]="showErrors" *ngIf="noticeOfPublicHearing.length === 0"></app-no-data>
5454
</div>
5555

5656
<div class="subheading2 grid-1">Proof of Signage</div>
5757
<div class="grid-double">
5858
<div *ngFor="let file of proofOfSignage">
59-
<a routerLink="/document/{{ file.documentUuid }}" target="_blank">
60-
{{ file.fileName }}
61-
</a>
59+
<a class="mobile" (click)="downloadFile(file.documentUuid)">{{ file.fileName }}</a>
60+
<a class="desktop" routerLink="/document/{{ file.documentUuid }}" target="_blank">{{ file.fileName }}</a>
6261
</div>
6362
<app-no-data [showRequired]="showErrors" *ngIf="proofOfSignage.length === 0"></app-no-data>
6463
</div>
6564

6665
<div class="subheading2 grid-1">Report of Public Hearing</div>
6766
<div class="grid-double">
6867
<div *ngFor="let file of reportOfPublicHearing">
69-
<a routerLink="/document/{{ file.documentUuid }}" target="_blank">
70-
{{ file.fileName }}
71-
</a>
68+
<a class="mobile" (click)="downloadFile(file.documentUuid)">{{ file.fileName }}</a>
69+
<a class="desktop" routerLink="/document/{{ file.documentUuid }}" target="_blank">{{ file.fileName }}</a>
7270
</div>
7371
<app-no-data [showRequired]="showErrors" *ngIf="reportOfPublicHearing.length === 0"></app-no-data>
7472
</div>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
@use '../../../../../styles/functions' as *;
2+
3+
.mobile {
4+
@media screen and (min-width: $tabletBreakpoint) {
5+
display: none;
6+
}
7+
}
8+
9+
.desktop {
10+
display: none;
11+
12+
@media screen and (min-width: $tabletBreakpoint) {
13+
display: inline;
14+
}
15+
}

portal-frontend/src/app/features/applications/application-details/excl-details/excl-details.component.spec.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,26 @@
11
import { ComponentFixture, TestBed } from '@angular/core/testing';
2-
import { DeepMocked } from '@golevelup/ts-jest';
2+
import { createMock, DeepMocked } from '@golevelup/ts-jest';
33

44
import { ExclDetailsComponent } from './excl-details.component';
55
import { ApplicationDocumentService } from '../../../../services/application-document/application-document.service';
66
import { ApplicationParcelService } from '../../../../services/application-parcel/application-parcel.service';
7+
import { HttpClient } from '@angular/common/http';
8+
import { DocumentService } from '../../../../services/document/document.service';
79

810
describe('ExclDetailsComponent', () => {
911
let component: ExclDetailsComponent;
1012
let fixture: ComponentFixture<ExclDetailsComponent>;
1113
let mockAppDocumentService: DeepMocked<ApplicationDocumentService>;
1214
let mockAppParcelService: DeepMocked<ApplicationParcelService>;
15+
let mockHttpClient: DeepMocked<HttpClient>;
16+
let mockDocumentService: DeepMocked<DocumentService>;
1317

1418
beforeEach(async () => {
19+
mockAppDocumentService = createMock();
20+
mockAppParcelService = createMock();
21+
mockHttpClient = createMock();
22+
mockDocumentService = createMock();
23+
1524
await TestBed.configureTestingModule({
1625
declarations: [ExclDetailsComponent],
1726
providers: [
@@ -23,6 +32,14 @@ describe('ExclDetailsComponent', () => {
2332
provide: ApplicationParcelService,
2433
useValue: mockAppParcelService,
2534
},
35+
{
36+
provide: HttpClient,
37+
useValue: mockHttpClient,
38+
},
39+
{
40+
provide: DocumentService,
41+
useValue: mockDocumentService,
42+
},
2643
],
2744
}).compileComponents();
2845

0 commit comments

Comments
 (0)