1
1
import { ChangeDetectionStrategy , Component , Input , OnChanges } from '@angular/core' ;
2
2
import { NavigationExtras } from '@angular/router' ;
3
- import { NavigationParams , NavigationPath , NavigationService } from '@hypertrace/common' ;
3
+ import {
4
+ ExternalNavigationParams ,
5
+ ExternalNavigationWindowHandling ,
6
+ NavigationParams ,
7
+ NavigationParamsType ,
8
+ NavigationPath ,
9
+ NavigationService ,
10
+ assertUnreachable
11
+ } from '@hypertrace/common' ;
4
12
import { isNil } from 'lodash-es' ;
5
13
import { EMPTY , Observable } from 'rxjs' ;
6
14
@@ -9,21 +17,40 @@ import { EMPTY, Observable } from 'rxjs';
9
17
styleUrls : [ './link.component.scss' ] ,
10
18
changeDetection : ChangeDetectionStrategy . OnPush ,
11
19
template : `
12
- <a
13
- *htLetAsync="this.navData$ as navData"
14
- class="ht-link"
15
- [ngClass]="{ disabled: this.disabled || !navData }"
16
- [routerLink]="navData?.path"
17
- [queryParams]="navData?.extras?.queryParams"
18
- [queryParamsHandling]="navData?.extras?.queryParamsHandling"
19
- [skipLocationChange]="navData?.extras?.skipLocationChange"
20
- [replaceUrl]="navData?.extras?.replaceUrl"
21
- [htTrack]
22
- htTrackLabel="{{ navData && navData.path ? navData.path : '' }}"
23
- [attr.aria-label]="this.ariaLabel"
24
- >
25
- <ng-content></ng-content>
26
- </a>
20
+ <ng-container *htLetAsync="this.navData$ as navData">
21
+ <ng-template #contentHolder>
22
+ <ng-content></ng-content>
23
+ </ng-template>
24
+
25
+ <ng-container *ngIf="this.externalNavParams; else internalLinkTemplate">
26
+ <a
27
+ class="ht-link external"
28
+ [ngClass]="{ disabled: this.disabled || !navData }"
29
+ [attr.href]="this.externalNavParams.url"
30
+ [attr.aria-label]="this.ariaLabel"
31
+ (click)="this.onExternalLinkClick($event, this.externalNavParams)"
32
+ >
33
+ <ng-container *ngTemplateOutlet="contentHolder"></ng-container>
34
+ </a>
35
+ </ng-container>
36
+
37
+ <ng-template #internalLinkTemplate>
38
+ <a
39
+ class="ht-link internal"
40
+ [ngClass]="{ disabled: this.disabled || !navData }"
41
+ [routerLink]="navData?.path"
42
+ [queryParams]="navData?.extras?.queryParams"
43
+ [queryParamsHandling]="navData?.extras?.queryParamsHandling"
44
+ [skipLocationChange]="navData?.extras?.skipLocationChange"
45
+ [replaceUrl]="navData?.extras?.replaceUrl"
46
+ [htTrack]
47
+ htTrackLabel="{{ navData && navData.path ? navData.path : '' }}"
48
+ [attr.aria-label]="this.ariaLabel"
49
+ >
50
+ <ng-container *ngTemplateOutlet="contentHolder"></ng-container>
51
+ </a>
52
+ </ng-template>
53
+ </ng-container>
27
54
`
28
55
} )
29
56
export class LinkComponent implements OnChanges {
@@ -37,12 +64,56 @@ export class LinkComponent implements OnChanges {
37
64
public ariaLabel ?: string ;
38
65
39
66
public navData$ : Observable < NavData > = EMPTY ;
67
+ public isExternal : boolean = false ;
68
+ public externalNavParams ?: ExternalNavigationParams ;
40
69
41
70
public constructor ( private readonly navigationService : NavigationService ) { }
42
71
43
72
public ngOnChanges ( ) : void {
73
+ this . externalNavParams = this . checkAndBuildExternalNavParams ( ) ;
44
74
this . navData$ = isNil ( this . paramsOrUrl ) ? EMPTY : this . navigationService . buildNavigationParams$ ( this . paramsOrUrl ) ;
45
75
}
76
+
77
+ public onExternalLinkClick ( event : MouseEvent , externalNavParams : ExternalNavigationParams ) : void {
78
+ event . preventDefault ( ) ;
79
+ window . open ( externalNavParams . url , this . asWindowName ( externalNavParams . windowHandling ) ) ;
80
+ }
81
+
82
+ private asWindowName ( windowHandling : ExternalNavigationWindowHandling ) : string | undefined {
83
+ switch ( windowHandling ) {
84
+ case ExternalNavigationWindowHandling . SameWindow :
85
+ return '_self' ;
86
+ case ExternalNavigationWindowHandling . NewWindow :
87
+ return undefined ;
88
+ default :
89
+ assertUnreachable ( windowHandling ) ;
90
+ }
91
+ }
92
+
93
+ private checkAndBuildExternalNavParams ( ) : ExternalNavigationParams | undefined {
94
+ if ( isNil ( this . paramsOrUrl ) ) {
95
+ return undefined ;
96
+ }
97
+
98
+ if ( typeof this . paramsOrUrl === 'string' && this . navigationService . isExternalUrl ( this . paramsOrUrl ) ) {
99
+ return {
100
+ navType : NavigationParamsType . External ,
101
+ url : this . paramsOrUrl ,
102
+ windowHandling : ExternalNavigationWindowHandling . SameWindow
103
+ } ;
104
+ }
105
+
106
+ if ( typeof this . paramsOrUrl !== 'string' && this . paramsOrUrl . navType === NavigationParamsType . External ) {
107
+ return {
108
+ ...this . paramsOrUrl ,
109
+ url : this . paramsOrUrl . useGlobalParams
110
+ ? this . navigationService . constructExternalUrl ( this . paramsOrUrl . url )
111
+ : this . paramsOrUrl . url
112
+ } ;
113
+ }
114
+
115
+ return undefined ;
116
+ }
46
117
}
47
118
48
119
interface NavData {
0 commit comments