From ff5f23017a5d003a3613c88d74c5d8e8f26485b5 Mon Sep 17 00:00:00 2001 From: lotte Date: Wed, 26 Mar 2025 17:59:31 +0100 Subject: [PATCH 1/3] 129694: PoC #4099 solution with resolvers --- .../collection-page.component.html | 1 - .../community-page.component.html | 1 - src/app/home-page/home-page.component.html | 3 - .../full/full-item-page.component.html | 1 - .../item-page/simple/item-page.component.html | 1 - .../dspace/view-tracker-resolver.service.ts | 66 +++++++++++++++++++ .../dspace/view-tracker.component.html | 1 - .../dspace/view-tracker.component.scss | 3 - .../dspace/view-tracker.component.ts | 56 ---------------- .../dspace/view-tracker.resolver.ts | 11 ++++ 10 files changed, 77 insertions(+), 67 deletions(-) create mode 100644 src/app/statistics/angulartics/dspace/view-tracker-resolver.service.ts delete mode 100644 src/app/statistics/angulartics/dspace/view-tracker.component.html delete mode 100644 src/app/statistics/angulartics/dspace/view-tracker.component.scss delete mode 100644 src/app/statistics/angulartics/dspace/view-tracker.component.ts create mode 100644 src/app/statistics/angulartics/dspace/view-tracker.resolver.ts diff --git a/src/app/collection-page/collection-page.component.html b/src/app/collection-page/collection-page.component.html index 02c63d316d..1b9b810ea0 100644 --- a/src/app/collection-page/collection-page.component.html +++ b/src/app/collection-page/collection-page.component.html @@ -3,7 +3,6 @@ *ngVar="(collectionRD$ | async) as collectionRD">
-
diff --git a/src/app/community-page/community-page.component.html b/src/app/community-page/community-page.component.html index 6d5262d933..f36a59b23c 100644 --- a/src/app/community-page/community-page.component.html +++ b/src/app/community-page/community-page.component.html @@ -1,7 +1,6 @@
-
diff --git a/src/app/home-page/home-page.component.html b/src/app/home-page/home-page.component.html index caa86ac290..e217e41a37 100644 --- a/src/app/home-page/home-page.component.html +++ b/src/app/home-page/home-page.component.html @@ -1,8 +1,5 @@
- - - diff --git a/src/app/item-page/full/full-item-page.component.html b/src/app/item-page/full/full-item-page.component.html index 1d83181395..39f682113a 100644 --- a/src/app/item-page/full/full-item-page.component.html +++ b/src/app/item-page/full/full-item-page.component.html @@ -3,7 +3,6 @@
-
diff --git a/src/app/item-page/simple/item-page.component.html b/src/app/item-page/simple/item-page.component.html index cc9983bb35..5e2dc63ee9 100644 --- a/src/app/item-page/simple/item-page.component.html +++ b/src/app/item-page/simple/item-page.component.html @@ -3,7 +3,6 @@
-
diff --git a/src/app/statistics/angulartics/dspace/view-tracker-resolver.service.ts b/src/app/statistics/angulartics/dspace/view-tracker-resolver.service.ts new file mode 100644 index 0000000000..f9a24e091a --- /dev/null +++ b/src/app/statistics/angulartics/dspace/view-tracker-resolver.service.ts @@ -0,0 +1,66 @@ +import { + AfterViewChecked, AfterViewInit, + Component, Injectable, + Input, + OnDestroy, + OnInit, +} from '@angular/core'; +import { Angulartics2 } from 'angulartics2'; +import { Observable, Subscription, switchMap } from 'rxjs'; +import { filter, take } from 'rxjs/operators'; + +import { ReferrerService } from '../../../core/services/referrer.service'; +import { DSpaceObject } from '../../../core/shared/dspace-object.model'; +import { hasValue } from '../../../shared/empty.util'; +import { ActivatedRoute, ActivatedRouteSnapshot, Resolve, ResolveEnd, Router, RouterStateSnapshot } from '@angular/router'; +import { BreadcrumbConfig } from '../../../breadcrumbs/breadcrumb/breadcrumb-config.model'; +import { SubmissionObject } from '../../../core/submission/models/submission-object.model'; + +/** + * This component triggers a page view statistic + */ +@Injectable({ + providedIn: 'root' +}) +export class ViewTrackerResolverService { + + constructor( + public angulartics2: Angulartics2, + public referrerService: ReferrerService, + public router: Router, + ) { + } + + resolve(routeSnapshot: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { + const dsoPath = routeSnapshot.data['dsoPath'] || 'dso.payload'; // Fetch the resolvers passed via the route data + this.router.events.pipe( + filter(event => event instanceof ResolveEnd), + take(1), + switchMap(() => + this.referrerService.getReferrer().pipe(take(1)))) + .subscribe((referrer: string) => { + this.angulartics2.eventTrack.next({ + action: 'page_view', + properties: { + object: this.getNestedProperty(routeSnapshot.data, dsoPath), + referrer, + }, + }); + }); + return true; + } + + private getNestedProperty(obj: any, path: string) { + const keys = path.split('.'); + let result = obj; + + for (const key of keys) { + if (result && result.hasOwnProperty(key)) { + result = result[key]; + } else { + return undefined; + } + } + return result; + } +} diff --git a/src/app/statistics/angulartics/dspace/view-tracker.component.html b/src/app/statistics/angulartics/dspace/view-tracker.component.html deleted file mode 100644 index c0c0ffe181..0000000000 --- a/src/app/statistics/angulartics/dspace/view-tracker.component.html +++ /dev/null @@ -1 +0,0 @@ -  diff --git a/src/app/statistics/angulartics/dspace/view-tracker.component.scss b/src/app/statistics/angulartics/dspace/view-tracker.component.scss deleted file mode 100644 index c76cafbe44..0000000000 --- a/src/app/statistics/angulartics/dspace/view-tracker.component.scss +++ /dev/null @@ -1,3 +0,0 @@ -:host { - display: none -} diff --git a/src/app/statistics/angulartics/dspace/view-tracker.component.ts b/src/app/statistics/angulartics/dspace/view-tracker.component.ts deleted file mode 100644 index 805d311cfd..0000000000 --- a/src/app/statistics/angulartics/dspace/view-tracker.component.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Component, Input, OnInit, OnDestroy } from '@angular/core'; -import { Angulartics2 } from 'angulartics2'; -import { DSpaceObject } from '../../../core/shared/dspace-object.model'; -import { Subscription } from 'rxjs/internal/Subscription'; -import { take } from 'rxjs/operators'; -import { hasValue } from '../../../shared/empty.util'; -import { ReferrerService } from '../../../core/services/referrer.service'; - -/** - * This component triggers a page view statistic - */ -@Component({ - selector: 'ds-view-tracker', - styleUrls: ['./view-tracker.component.scss'], - templateUrl: './view-tracker.component.html', -}) -export class ViewTrackerComponent implements OnInit, OnDestroy { - /** - * The DSpaceObject to track a view event about - */ - @Input() object: DSpaceObject; - - /** - * The subscription on this.referrerService.getReferrer() - * @protected - */ - protected sub: Subscription; - - constructor( - public angulartics2: Angulartics2, - public referrerService: ReferrerService - ) { - } - - ngOnInit(): void { - this.sub = this.referrerService.getReferrer() - .pipe(take(1)) - .subscribe((referrer: string) => { - this.angulartics2.eventTrack.next({ - action: 'page_view', - properties: { - object: this.object, - referrer - }, - }); - }); - } - - ngOnDestroy(): void { - // unsubscribe in the case that this component is destroyed before - // this.referrerService.getReferrer() has emitted - if (hasValue(this.sub)) { - this.sub.unsubscribe(); - } - } -} diff --git a/src/app/statistics/angulartics/dspace/view-tracker.resolver.ts b/src/app/statistics/angulartics/dspace/view-tracker.resolver.ts new file mode 100644 index 0000000000..9b98185d61 --- /dev/null +++ b/src/app/statistics/angulartics/dspace/view-tracker.resolver.ts @@ -0,0 +1,11 @@ +import { inject } from '@angular/core'; +import { ActivatedRouteSnapshot, ResolveFn, RouterStateSnapshot, } from '@angular/router'; +import { ViewTrackerResolverService } from './view-tracker-resolver.service'; + +export const viewTrackerResolver: ResolveFn = ( + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot, + viewTrackerResolverService: ViewTrackerResolverService = inject(ViewTrackerResolverService), +): boolean => { + return viewTrackerResolverService.resolve(route, state); +}; From 01becae7d0a99ea2d99d1e28d6e75c5f7f64b882 Mon Sep 17 00:00:00 2001 From: lotte Date: Fri, 4 Apr 2025 13:31:49 +0200 Subject: [PATCH 2/3] 129694: backported view tracker resolver --- src/app/app-routing.module.ts | 13 ++++++++++++- .../collection-page-routing.module.ts | 5 +++++ .../community-page/community-page-routing.module.ts | 5 +++++ src/app/home-page/home-page-routing.module.ts | 6 ------ src/app/item-page/item-page-routing.module.ts | 10 +++++++++- .../angulartics/dspace/view-tracker.resolver.ts | 11 ----------- src/app/statistics/statistics.module.ts | 3 --- 7 files changed, 31 insertions(+), 22 deletions(-) delete mode 100644 src/app/statistics/angulartics/dspace/view-tracker.resolver.ts diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index deb68f1ea9..b81201dd01 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -40,6 +40,8 @@ import { import { ServerCheckGuard } from './core/server-check/server-check.guard'; import { MenuResolver } from './menu.resolver'; import { ThemedPageErrorComponent } from './page-error/themed-page-error.component'; +import { HomePageResolver } from './home-page/home-page.resolver'; +import { ViewTrackerResolverService } from './statistics/angulartics/dspace/view-tracker-resolver.service'; @NgModule({ imports: [ @@ -63,7 +65,15 @@ import { ThemedPageErrorComponent } from './page-error/themed-page-error.compone path: 'home', loadChildren: () => import('./home-page/home-page.module') .then((m) => m.HomePageModule), - data: { showBreadcrumbs: false }, + data: { + showBreadcrumbs: false, + dsoPath: 'site' + }, + resolve: { + site: HomePageResolver, + tracking: ViewTrackerResolverService, + }, + canActivate: [EndUserAgreementCurrentUserGuard] }, { @@ -251,6 +261,7 @@ import { ThemedPageErrorComponent } from './page-error/themed-page-error.compone }) ], exports: [RouterModule], + providers: [HomePageResolver, ViewTrackerResolverService], }) export class AppRoutingModule { diff --git a/src/app/collection-page/collection-page-routing.module.ts b/src/app/collection-page/collection-page-routing.module.ts index 9dc25b778e..23a267bd03 100644 --- a/src/app/collection-page/collection-page-routing.module.ts +++ b/src/app/collection-page/collection-page-routing.module.ts @@ -22,6 +22,7 @@ import { LinkMenuItemModel } from '../shared/menu/menu-item/models/link.model'; import { ThemedCollectionPageComponent } from './themed-collection-page.component'; import { MenuItemType } from '../shared/menu/menu-item-type.model'; import { DSOEditMenuResolver } from '../shared/dso-page/dso-edit-menu.resolver'; +import { ViewTrackerResolverService } from '../statistics/angulartics/dspace/view-tracker-resolver.service'; @NgModule({ imports: [ @@ -66,6 +67,9 @@ import { DSOEditMenuResolver } from '../shared/dso-page/dso-edit-menu.resolver'; path: '', component: ThemedCollectionPageComponent, pathMatch: 'full', + resolve: { + tracking: ViewTrackerResolverService, + }, } ], data: { @@ -94,6 +98,7 @@ import { DSOEditMenuResolver } from '../shared/dso-page/dso-edit-menu.resolver'; LinkService, CreateCollectionPageGuard, CollectionPageAdministratorGuard, + ViewTrackerResolverService, ] }) export class CollectionPageRoutingModule { diff --git a/src/app/community-page/community-page-routing.module.ts b/src/app/community-page/community-page-routing.module.ts index c37f8832f8..48206d7dfc 100644 --- a/src/app/community-page/community-page-routing.module.ts +++ b/src/app/community-page/community-page-routing.module.ts @@ -15,6 +15,7 @@ import { LinkMenuItemModel } from '../shared/menu/menu-item/models/link.model'; import { ThemedCommunityPageComponent } from './themed-community-page.component'; import { MenuItemType } from '../shared/menu/menu-item-type.model'; import { DSOEditMenuResolver } from '../shared/dso-page/dso-edit-menu.resolver'; +import { ViewTrackerResolverService } from '../statistics/angulartics/dspace/view-tracker-resolver.service'; @NgModule({ imports: [ @@ -49,6 +50,9 @@ import { DSOEditMenuResolver } from '../shared/dso-page/dso-edit-menu.resolver'; path: '', component: ThemedCommunityPageComponent, pathMatch: 'full', + resolve: { + tracking: ViewTrackerResolverService, + }, } ], data: { @@ -76,6 +80,7 @@ import { DSOEditMenuResolver } from '../shared/dso-page/dso-edit-menu.resolver'; LinkService, CreateCommunityPageGuard, CommunityPageAdministratorGuard, + ViewTrackerResolverService, ] }) export class CommunityPageRoutingModule { diff --git a/src/app/home-page/home-page-routing.module.ts b/src/app/home-page/home-page-routing.module.ts index 196a290552..aaac25c455 100644 --- a/src/app/home-page/home-page-routing.module.ts +++ b/src/app/home-page/home-page-routing.module.ts @@ -28,15 +28,9 @@ import { MenuItemType } from '../shared/menu/menu-item-type.model'; } as LinkMenuItemModel, }], }, - }, - resolve: { - site: HomePageResolver } } ]) - ], - providers: [ - HomePageResolver ] }) export class HomePageRoutingModule { diff --git a/src/app/item-page/item-page-routing.module.ts b/src/app/item-page/item-page-routing.module.ts index 0c855ab34d..084c314d82 100644 --- a/src/app/item-page/item-page-routing.module.ts +++ b/src/app/item-page/item-page-routing.module.ts @@ -19,6 +19,7 @@ import { REQUEST_COPY_MODULE_PATH } from '../app-routing-paths'; import { OrcidPageComponent } from './orcid-page/orcid-page.component'; import { OrcidPageGuard } from './orcid-page/orcid-page.guard'; import { DSOEditMenuResolver } from '../shared/dso-page/dso-edit-menu.resolver'; +import { ViewTrackerResolverService } from '../statistics/angulartics/dspace/view-tracker-resolver.service'; @NgModule({ imports: [ @@ -36,10 +37,16 @@ import { DSOEditMenuResolver } from '../shared/dso-page/dso-edit-menu.resolver'; path: '', component: ThemedItemPageComponent, pathMatch: 'full', + resolve: { + tracking: ViewTrackerResolverService, + } }, { path: 'full', component: ThemedFullItemPageComponent, + resolve: { + tracking: ViewTrackerResolverService, + } }, { path: ITEM_EDIT_PATH, @@ -98,7 +105,8 @@ import { DSOEditMenuResolver } from '../shared/dso-page/dso-edit-menu.resolver'; LinkService, ItemPageAdministratorGuard, VersionResolver, - OrcidPageGuard + OrcidPageGuard, + ViewTrackerResolverService, ] }) diff --git a/src/app/statistics/angulartics/dspace/view-tracker.resolver.ts b/src/app/statistics/angulartics/dspace/view-tracker.resolver.ts deleted file mode 100644 index 9b98185d61..0000000000 --- a/src/app/statistics/angulartics/dspace/view-tracker.resolver.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { inject } from '@angular/core'; -import { ActivatedRouteSnapshot, ResolveFn, RouterStateSnapshot, } from '@angular/router'; -import { ViewTrackerResolverService } from './view-tracker-resolver.service'; - -export const viewTrackerResolver: ResolveFn = ( - route: ActivatedRouteSnapshot, - state: RouterStateSnapshot, - viewTrackerResolverService: ViewTrackerResolverService = inject(ViewTrackerResolverService), -): boolean => { - return viewTrackerResolverService.resolve(route, state); -}; diff --git a/src/app/statistics/statistics.module.ts b/src/app/statistics/statistics.module.ts index 4870e4fbf0..d93d774394 100644 --- a/src/app/statistics/statistics.module.ts +++ b/src/app/statistics/statistics.module.ts @@ -2,7 +2,6 @@ import { ModuleWithProviders, NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { CoreModule } from '../core/core.module'; import { SharedModule } from '../shared/shared.module'; -import { ViewTrackerComponent } from './angulartics/dspace/view-tracker.component'; import { StatisticsEndpoint } from './statistics-endpoint.model'; /** @@ -19,10 +18,8 @@ export const models = [ SharedModule, ], declarations: [ - ViewTrackerComponent, ], exports: [ - ViewTrackerComponent, ] }) /** From edd5496a4d946c8391e7171af2969a2a7cfc7c0e Mon Sep 17 00:00:00 2001 From: lotte Date: Fri, 4 Apr 2025 15:11:02 +0200 Subject: [PATCH 3/3] 129694: Fixed lint issues --- src/app/home-page/home-page-routing.module.ts | 1 - .../dspace/view-tracker-resolver.service.ts | 18 ++++-------------- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/src/app/home-page/home-page-routing.module.ts b/src/app/home-page/home-page-routing.module.ts index aaac25c455..b95a258613 100644 --- a/src/app/home-page/home-page-routing.module.ts +++ b/src/app/home-page/home-page-routing.module.ts @@ -1,7 +1,6 @@ import { NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; -import { HomePageResolver } from './home-page.resolver'; import { LinkMenuItemModel } from '../shared/menu/menu-item/models/link.model'; import { ThemedHomePageComponent } from './themed-home-page.component'; import { MenuItemType } from '../shared/menu/menu-item-type.model'; diff --git a/src/app/statistics/angulartics/dspace/view-tracker-resolver.service.ts b/src/app/statistics/angulartics/dspace/view-tracker-resolver.service.ts index f9a24e091a..fc23c09c51 100644 --- a/src/app/statistics/angulartics/dspace/view-tracker-resolver.service.ts +++ b/src/app/statistics/angulartics/dspace/view-tracker-resolver.service.ts @@ -1,20 +1,10 @@ -import { - AfterViewChecked, AfterViewInit, - Component, Injectable, - Input, - OnDestroy, - OnInit, -} from '@angular/core'; +import { Injectable, } from '@angular/core'; import { Angulartics2 } from 'angulartics2'; -import { Observable, Subscription, switchMap } from 'rxjs'; +import { switchMap } from 'rxjs'; import { filter, take } from 'rxjs/operators'; import { ReferrerService } from '../../../core/services/referrer.service'; -import { DSpaceObject } from '../../../core/shared/dspace-object.model'; -import { hasValue } from '../../../shared/empty.util'; -import { ActivatedRoute, ActivatedRouteSnapshot, Resolve, ResolveEnd, Router, RouterStateSnapshot } from '@angular/router'; -import { BreadcrumbConfig } from '../../../breadcrumbs/breadcrumb/breadcrumb-config.model'; -import { SubmissionObject } from '../../../core/submission/models/submission-object.model'; +import { ActivatedRouteSnapshot, ResolveEnd, Router, RouterStateSnapshot } from '@angular/router'; /** * This component triggers a page view statistic @@ -32,7 +22,7 @@ export class ViewTrackerResolverService { } resolve(routeSnapshot: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { - const dsoPath = routeSnapshot.data['dsoPath'] || 'dso.payload'; // Fetch the resolvers passed via the route data + const dsoPath = routeSnapshot.data.dsoPath || 'dso.payload'; // Fetch the resolvers passed via the route data this.router.events.pipe( filter(event => event instanceof ResolveEnd), take(1),