Merge branch 'backport-4099-duplicate-view-events-7.6' into 4099-duplicate-view-events_contibute-7.6.3

This commit is contained in:
lotte
2025-04-07 10:43:09 +02:00
15 changed files with 79 additions and 79 deletions

View File

@@ -40,6 +40,8 @@ import {
import { ServerCheckGuard } from './core/server-check/server-check.guard'; import { ServerCheckGuard } from './core/server-check/server-check.guard';
import { MenuResolver } from './menu.resolver'; import { MenuResolver } from './menu.resolver';
import { ThemedPageErrorComponent } from './page-error/themed-page-error.component'; 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({ @NgModule({
imports: [ imports: [
@@ -63,7 +65,15 @@ import { ThemedPageErrorComponent } from './page-error/themed-page-error.compone
path: 'home', path: 'home',
loadChildren: () => import('./home-page/home-page.module') loadChildren: () => import('./home-page/home-page.module')
.then((m) => m.HomePageModule), .then((m) => m.HomePageModule),
data: { showBreadcrumbs: false }, data: {
showBreadcrumbs: false,
dsoPath: 'site'
},
resolve: {
site: HomePageResolver,
tracking: ViewTrackerResolverService,
},
canActivate: [EndUserAgreementCurrentUserGuard] canActivate: [EndUserAgreementCurrentUserGuard]
}, },
{ {
@@ -251,6 +261,7 @@ import { ThemedPageErrorComponent } from './page-error/themed-page-error.compone
}) })
], ],
exports: [RouterModule], exports: [RouterModule],
providers: [HomePageResolver, ViewTrackerResolverService],
}) })
export class AppRoutingModule { export class AppRoutingModule {

View File

@@ -23,6 +23,7 @@ import { ThemedCollectionPageComponent } from './themed-collection-page.componen
import { MenuItemType } from '../shared/menu/menu-item-type.model'; import { MenuItemType } from '../shared/menu/menu-item-type.model';
import { DSOEditMenuResolver } from '../shared/dso-page/dso-edit-menu.resolver'; import { DSOEditMenuResolver } from '../shared/dso-page/dso-edit-menu.resolver';
import { CommunityBreadcrumbResolver } from '../core/breadcrumbs/community-breadcrumb.resolver'; import { CommunityBreadcrumbResolver } from '../core/breadcrumbs/community-breadcrumb.resolver';
import { ViewTrackerResolverService } from '../statistics/angulartics/dspace/view-tracker-resolver.service';
@NgModule({ @NgModule({
imports: [ imports: [
@@ -86,6 +87,7 @@ import { CommunityBreadcrumbResolver } from '../core/breadcrumbs/community-bread
pathMatch: 'full', pathMatch: 'full',
resolve: { resolve: {
menu: DSOEditMenuResolver, menu: DSOEditMenuResolver,
tracking: ViewTrackerResolverService,
}, },
} }
], ],
@@ -116,6 +118,7 @@ import { CommunityBreadcrumbResolver } from '../core/breadcrumbs/community-bread
CreateCollectionPageGuard, CreateCollectionPageGuard,
CollectionPageAdministratorGuard, CollectionPageAdministratorGuard,
CommunityBreadcrumbResolver, CommunityBreadcrumbResolver,
ViewTrackerResolverService,
] ]
}) })
export class CollectionPageRoutingModule { export class CollectionPageRoutingModule {

View File

@@ -3,7 +3,6 @@
*ngVar="(collectionRD$ | async) as collectionRD"> *ngVar="(collectionRD$ | async) as collectionRD">
<div *ngIf="collectionRD?.hasSucceeded" @fadeInOut> <div *ngIf="collectionRD?.hasSucceeded" @fadeInOut>
<div *ngIf="collectionRD?.payload as collection"> <div *ngIf="collectionRD?.payload as collection">
<ds-view-tracker [object]="collection"></ds-view-tracker>
<div class="d-flex flex-row border-bottom mb-4 pb-4"> <div class="d-flex flex-row border-bottom mb-4 pb-4">
<header class="comcol-header mr-auto"> <header class="comcol-header mr-auto">
<!-- Collection Name --> <!-- Collection Name -->

View File

@@ -16,6 +16,7 @@ import { ThemedCommunityPageComponent } from './themed-community-page.component'
import { MenuItemType } from '../shared/menu/menu-item-type.model'; import { MenuItemType } from '../shared/menu/menu-item-type.model';
import { DSOEditMenuResolver } from '../shared/dso-page/dso-edit-menu.resolver'; import { DSOEditMenuResolver } from '../shared/dso-page/dso-edit-menu.resolver';
import { I18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.resolver'; import { I18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.resolver';
import { ViewTrackerResolverService } from '../statistics/angulartics/dspace/view-tracker-resolver.service';
@NgModule({ @NgModule({
imports: [ imports: [
@@ -69,6 +70,7 @@ import { I18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.reso
pathMatch: 'full', pathMatch: 'full',
resolve: { resolve: {
menu: DSOEditMenuResolver, menu: DSOEditMenuResolver,
tracking: ViewTrackerResolverService,
}, },
} }
], ],
@@ -97,6 +99,7 @@ import { I18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.reso
LinkService, LinkService,
CreateCommunityPageGuard, CreateCommunityPageGuard,
CommunityPageAdministratorGuard, CommunityPageAdministratorGuard,
ViewTrackerResolverService,
] ]
}) })
export class CommunityPageRoutingModule { export class CommunityPageRoutingModule {

View File

@@ -1,7 +1,6 @@
<div class="container" *ngVar="(communityRD$ | async) as communityRD"> <div class="container" *ngVar="(communityRD$ | async) as communityRD">
<div class="community-page" *ngIf="communityRD?.hasSucceeded" @fadeInOut> <div class="community-page" *ngIf="communityRD?.hasSucceeded" @fadeInOut>
<div *ngIf="communityRD?.payload; let communityPayload"> <div *ngIf="communityRD?.payload; let communityPayload">
<ds-view-tracker [object]="communityPayload"></ds-view-tracker>
<div class="d-flex flex-row border-bottom mb-4 pb-4"> <div class="d-flex flex-row border-bottom mb-4 pb-4">
<header class="comcol-header mr-auto"> <header class="comcol-header mr-auto">
<!-- Community name --> <!-- Community name -->

View File

@@ -1,7 +1,6 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router'; import { RouterModule } from '@angular/router';
import { HomePageResolver } from './home-page.resolver';
import { LinkMenuItemModel } from '../shared/menu/menu-item/models/link.model'; import { LinkMenuItemModel } from '../shared/menu/menu-item/models/link.model';
import { ThemedHomePageComponent } from './themed-home-page.component'; import { ThemedHomePageComponent } from './themed-home-page.component';
import { MenuItemType } from '../shared/menu/menu-item-type.model'; import { MenuItemType } from '../shared/menu/menu-item-type.model';
@@ -28,15 +27,9 @@ import { MenuItemType } from '../shared/menu/menu-item-type.model';
} as LinkMenuItemModel, } as LinkMenuItemModel,
}], }],
}, },
},
resolve: {
site: HomePageResolver
} }
} }
]) ])
],
providers: [
HomePageResolver
] ]
}) })
export class HomePageRoutingModule { export class HomePageRoutingModule {

View File

@@ -1,8 +1,5 @@
<ds-themed-home-news></ds-themed-home-news> <ds-themed-home-news></ds-themed-home-news>
<div class="container"> <div class="container">
<ng-container *ngIf="(site$ | async) as site">
<ds-view-tracker [object]="site"></ds-view-tracker>
</ng-container>
<ds-themed-search-form [inPlaceSearch]="false" [searchPlaceholder]="'home.search-form.placeholder' | translate"></ds-themed-search-form> <ds-themed-search-form [inPlaceSearch]="false" [searchPlaceholder]="'home.search-form.placeholder' | translate"></ds-themed-search-form>
<ds-themed-top-level-community-list></ds-themed-top-level-community-list> <ds-themed-top-level-community-list></ds-themed-top-level-community-list>
<ds-recent-item-list *ngIf="recentSubmissionspageSize>0"></ds-recent-item-list> <ds-recent-item-list *ngIf="recentSubmissionspageSize>0"></ds-recent-item-list>

View File

@@ -3,7 +3,6 @@
<div *ngIf="itemRD?.payload as item"> <div *ngIf="itemRD?.payload as item">
<ds-themed-item-alerts [item]="item"></ds-themed-item-alerts> <ds-themed-item-alerts [item]="item"></ds-themed-item-alerts>
<ds-item-versions-notice [item]="item"></ds-item-versions-notice> <ds-item-versions-notice [item]="item"></ds-item-versions-notice>
<ds-view-tracker [object]="item"></ds-view-tracker>
<div *ngIf="!item.isWithdrawn || (isAdmin$|async)" class="full-item-info"> <div *ngIf="!item.isWithdrawn || (isAdmin$|async)" class="full-item-info">
<div class="d-flex flex-row"> <div class="d-flex flex-row">
<ds-themed-item-page-title-field class="mr-auto" [item]="item"></ds-themed-item-page-title-field> <ds-themed-item-page-title-field class="mr-auto" [item]="item"></ds-themed-item-page-title-field>

View File

@@ -19,6 +19,7 @@ import { REQUEST_COPY_MODULE_PATH } from '../app-routing-paths';
import { OrcidPageComponent } from './orcid-page/orcid-page.component'; import { OrcidPageComponent } from './orcid-page/orcid-page.component';
import { OrcidPageGuard } from './orcid-page/orcid-page.guard'; import { OrcidPageGuard } from './orcid-page/orcid-page.guard';
import { DSOEditMenuResolver } from '../shared/dso-page/dso-edit-menu.resolver'; import { DSOEditMenuResolver } from '../shared/dso-page/dso-edit-menu.resolver';
import { ViewTrackerResolverService } from '../statistics/angulartics/dspace/view-tracker-resolver.service';
@NgModule({ @NgModule({
imports: [ imports: [
@@ -37,6 +38,7 @@ import { DSOEditMenuResolver } from '../shared/dso-page/dso-edit-menu.resolver';
pathMatch: 'full', pathMatch: 'full',
resolve: { resolve: {
menu: DSOEditMenuResolver, menu: DSOEditMenuResolver,
tracking: ViewTrackerResolverService,
}, },
}, },
{ {
@@ -44,6 +46,7 @@ import { DSOEditMenuResolver } from '../shared/dso-page/dso-edit-menu.resolver';
component: ThemedFullItemPageComponent, component: ThemedFullItemPageComponent,
resolve: { resolve: {
menu: DSOEditMenuResolver, menu: DSOEditMenuResolver,
tracking: ViewTrackerResolverService,
}, },
}, },
{ {
@@ -103,7 +106,8 @@ import { DSOEditMenuResolver } from '../shared/dso-page/dso-edit-menu.resolver';
LinkService, LinkService,
ItemPageAdministratorGuard, ItemPageAdministratorGuard,
VersionResolver, VersionResolver,
OrcidPageGuard OrcidPageGuard,
ViewTrackerResolverService,
] ]
}) })

View File

@@ -3,7 +3,6 @@
<div *ngIf="itemRD?.payload as item"> <div *ngIf="itemRD?.payload as item">
<ds-themed-item-alerts [item]="item"></ds-themed-item-alerts> <ds-themed-item-alerts [item]="item"></ds-themed-item-alerts>
<ds-item-versions-notice [item]="item"></ds-item-versions-notice> <ds-item-versions-notice [item]="item"></ds-item-versions-notice>
<ds-view-tracker [object]="item"></ds-view-tracker>
<ds-listable-object-component-loader *ngIf="!item.isWithdrawn || (isAdmin$|async)" [object]="item" [viewMode]="viewMode"></ds-listable-object-component-loader> <ds-listable-object-component-loader *ngIf="!item.isWithdrawn || (isAdmin$|async)" [object]="item" [viewMode]="viewMode"></ds-listable-object-component-loader>
<ds-item-versions class="mt-2" [item]="item" [displayActions]="false"></ds-item-versions> <ds-item-versions class="mt-2" [item]="item" [displayActions]="false"></ds-item-versions>
</div> </div>

View File

@@ -0,0 +1,56 @@
import { Injectable, } from '@angular/core';
import { Angulartics2 } from 'angulartics2';
import { switchMap } from 'rxjs';
import { filter, take } from 'rxjs/operators';
import { ReferrerService } from '../../../core/services/referrer.service';
import { ActivatedRouteSnapshot, ResolveEnd, Router, RouterStateSnapshot } from '@angular/router';
/**
* 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;
}
}

View File

@@ -1,3 +0,0 @@
:host {
display: none
}

View File

@@ -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();
}
}
}

View File

@@ -2,7 +2,6 @@ import { ModuleWithProviders, NgModule } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { CoreModule } from '../core/core.module'; import { CoreModule } from '../core/core.module';
import { SharedModule } from '../shared/shared.module'; import { SharedModule } from '../shared/shared.module';
import { ViewTrackerComponent } from './angulartics/dspace/view-tracker.component';
import { StatisticsEndpoint } from './statistics-endpoint.model'; import { StatisticsEndpoint } from './statistics-endpoint.model';
/** /**
@@ -19,10 +18,8 @@ export const models = [
SharedModule, SharedModule,
], ],
declarations: [ declarations: [
ViewTrackerComponent,
], ],
exports: [ exports: [
ViewTrackerComponent,
] ]
}) })
/** /**