Skip to content

Commit c1a71f3

Browse files
Added analytics to release downloads and visualizations. Resolves #1067. (#1116)
1 parent d150bee commit c1a71f3

File tree

6 files changed

+109
-5
lines changed

6 files changed

+109
-5
lines changed

spa/src/app/files/releases/release-files-modal/release-files-modal.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ <h4 class="fontsize-l" [ngClass]="{'singleDataset': state.singleDataset}">
2121
<mat-table [dataSource]="state.releaseDataset.files">
2222
<ng-container matColumnDef="download">
2323
<mat-cell *matCellDef="let element" class="download fontsize-xxs">
24-
<a [href]="getReleaseFileUrl(element.url)"></a>
24+
<a [href]="getReleaseFileUrl(element.url)" (click)="trackDownload(element)"></a>
2525
</mat-cell>
2626
</ng-container>
2727
<ng-container matColumnDef="description">

spa/src/app/files/releases/release-files-modal/release-files-modal.component.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { BehaviorSubject, combineLatest, Subject } from "rxjs";
1919
import { filter, take, takeUntil } from "rxjs/operators";
2020

2121
// App dependencies
22-
import { Release } from "../release.model";
22+
import { ConfigService } from "../../../config/config.service";
2323
import { AppState } from "../../../_ngrx/app.state";
2424
import { ModalClosedAction } from "../../../modal/_ngrx/modal-closed.action";
2525
import { ModalOpenedAction } from "../../../modal/_ngrx/modal-opened.action";
@@ -33,9 +33,11 @@ import { SetReleaseReferrerAction } from "../../_ngrx/release/set-release-referr
3333
import { FetchProjectRequestAction } from "../../_ngrx/table/table.actions";
3434
import { ReleaseDatasetView } from "../release-dataset-view.model";
3535
import { ReleaseFilesModalState } from "./release-files-modal.state";
36+
import { Release } from "../release.model";
3637
import { ReleaseName } from "../release-name.model";
38+
import { ReleaseFileView } from "../release-file-view.model";
3739
import { ReleaseService } from "../../shared/release.service";
38-
import { ConfigService } from "../../../config/config.service";
40+
import { GTMService } from "../../../shared/gtm/gtm.service";
3941

4042
@Component({
4143
selector: "release-files-modal",
@@ -55,6 +57,7 @@ export class ReleaseFilesModalComponent implements OnDestroy, OnInit {
5557
/**
5658
* @param {Store<AppState>} store
5759
* @param {ConfigService} configService
60+
* @param {GTMService} gtmService
5861
* @param {ReleaseService} releaseService
5962
* @param {MatDialogRef<ProjectDownloadMatrixModalComponent>} dialogRef
6063
* @param {any} data
@@ -63,6 +66,7 @@ export class ReleaseFilesModalComponent implements OnDestroy, OnInit {
6366
constructor(
6467
private store: Store<AppState>,
6568
private configService: ConfigService,
69+
private gtmService: GTMService,
6670
private releaseService: ReleaseService,
6771
private dialogRef: MatDialogRef<ReleaseFilesModalComponent>,
6872
@Inject(MAT_DIALOG_DATA) private data: any,
@@ -112,6 +116,16 @@ export class ReleaseFilesModalComponent implements OnDestroy, OnInit {
112116
this.store.dispatch(new SetReleaseReferrerAction());
113117
}
114118

119+
/**
120+
* Track download of release file.
121+
*
122+
* @param {ReleaseFileView} releaseFile
123+
*/
124+
public trackDownload(releaseFile: ReleaseFileView): void {
125+
126+
this.gtmService.trackDownload(releaseFile.url);
127+
}
128+
115129
/**
116130
* Create model of dataset to back modal. The specified release is expected to have a single project containing a
117131
* single dataset; the dataset we want to display.

spa/src/app/files/releases/release-table/release-table.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ <h2 class="fontsize-xl">{{organView.organ}}</h2>
6969
[tooltipDisabled]="false"
7070
[tooltipPosition]="'above'">
7171
<a href={{visualization.url}} target="_blank"
72-
rel="noopener noreferrer">{{visualization.title}}</a>
72+
rel="noopener noreferrer" (click)="trackExternalLink(visualization.url)">{{visualization.title}}</a>
7373
</hca-tooltip>
7474
</ng-container>
7575
</mat-cell>

spa/src/app/files/releases/release-table/release-table.component.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { AppState } from "../../../_ngrx/app.state";
1414
import { SetReleaseReferrerAction } from "../../_ngrx/release/set-release-referrer.action";
1515
import { ReleaseOrganView } from "../release-organ-view.model";
1616
import { SetReleaseFilesReferrerAction } from "../../_ngrx/release/set-release-files-referrer.action";
17+
import { GTMService } from "../../../shared/gtm/gtm.service";
1718

1819
@Component({
1920
selector: "release-table",
@@ -29,9 +30,10 @@ export class ReleaseTableComponent {
2930
@Input() releaseFilesReferrer: boolean[];
3031

3132
/**
33+
* @param {GTMService} gtmService
3234
* @param {Store<AppState>} store
3335
*/
34-
constructor(private store: Store<AppState>) {}
36+
constructor(private gtmService: GTMService, private store: Store<AppState>) {}
3537

3638
/**
3739
* Returns the technology, based off libraryConstructionApproach. Any libraryConstructionApproach ending with
@@ -78,4 +80,15 @@ export class ReleaseTableComponent {
7880
this.store.dispatch(new SetReleaseReferrerAction());
7981
}
8082
}
83+
84+
85+
/**
86+
* Track click on link to external visualization tool.
87+
*
88+
* @param {string} url
89+
*/
90+
public trackExternalLink(url: string): void {
91+
92+
this.gtmService.trackExternalLink(url);
93+
}
8194
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/**
2+
* Human Cell Atlas
3+
* https://www.humancellatlas.org/
4+
*
5+
* Service handling Google Tag Manager-related functionality.
6+
*/
7+
8+
// Core dependencies
9+
import { Inject, Injectable } from "@angular/core";
10+
11+
@Injectable()
12+
export class GTMService {
13+
14+
private EVENT_NAME_DOWNLOAD = "download";
15+
private EVENT_NAME_EXTERNAL_LINK = "externalLink";
16+
17+
private dataLayer;
18+
19+
/**
20+
* @param {Window} window
21+
*/
22+
constructor(@Inject("Window") private window: Window) {
23+
24+
this.dataLayer = window["dataLayer"];
25+
}
26+
27+
/**
28+
* Send custom "download" GTM event.
29+
*
30+
* @param {string} url
31+
*/
32+
public trackDownload(url: string): void {
33+
34+
if ( !this.isTracking() ) {
35+
return;
36+
}
37+
this.trackEvent(this.EVENT_NAME_DOWNLOAD, {url});
38+
}
39+
40+
/**
41+
* Send custom "download" GTM event.
42+
*
43+
* @param {string} url
44+
*/
45+
public trackExternalLink(url: string): void {
46+
47+
if ( !this.isTracking() ) {
48+
return;
49+
}
50+
this.trackEvent(this.EVENT_NAME_EXTERNAL_LINK, {url});
51+
}
52+
53+
/**
54+
* Returns true if GTM is enabled.
55+
*
56+
* @returns {boolean}
57+
*/
58+
private isTracking(): boolean {
59+
60+
return !!this.dataLayer;
61+
}
62+
63+
/**
64+
* Track the specified event.
65+
*
66+
* @param {string} eventName
67+
* @param {any} eventVariables
68+
*/
69+
private trackEvent(eventName: string, eventVariables: any): void {
70+
71+
this.dataLayer.push(Object.assign({
72+
"event": eventName
73+
}, eventVariables));
74+
}
75+
}

spa/src/app/shared/shared.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { AnnouncementComponent } from "./announcement/announcement.component";
2020
import { CCToolbarNavComponent } from "./cc-toolbar-nav/cc-toolbar-nav.component";
2121
import { CCToolbarNavItemComponent } from "./cc-toolbar-nav-item/cc-toolbar-nav-item.component";
2222
import { DownloadButtonComponent } from "./download-button/download-button.component";
23+
import { GTMService } from "./gtm/gtm.service";
2324
import { HCASectionTitleComponent } from "./hca-section-title/hca-section-title.component";
2425
import { HCATabComponent } from "./hca-tab/hca-tab.component";
2526
import { KeyValuePairComponent } from "./key-value-pair/key-value-pair.component";
@@ -62,6 +63,7 @@ import { NavComponent } from "./nav/nav.component";
6263
WarningTitleComponent
6364
],
6465
providers: [
66+
GTMService,
6567
ResponsiveService
6668
],
6769
exports: [

0 commit comments

Comments
 (0)