1
0

Merge pull request #4232 from atmire/4099-duplicate-view-events_contibute-8.x

[Port to dspace-8_x] Fix for double view events when using dynamic themes
This commit is contained in:
Tim Donohue
2025-04-23 16:58:17 -05:00
committed by GitHub
27 changed files with 103 additions and 103 deletions

View File

@@ -33,6 +33,7 @@ import { reloadGuard } from './core/reload/reload.guard';
import { forgotPasswordCheckGuard } from './core/rest-property/forgot-password-check-guard.guard';
import { ServerCheckGuard } from './core/server-check/server-check.guard';
import { ThemedForbiddenComponent } from './forbidden/themed-forbidden.component';
import { homePageResolver } from './home-page/home-page.resolver';
import { ITEM_MODULE_PATH } from './item-page/item-page-routing-paths';
import { menuResolver } from './menuResolver';
import { provideSuggestionNotificationsState } from './notifications/provide-suggestion-notifications-state';
@@ -40,6 +41,7 @@ import { ThemedPageErrorComponent } from './page-error/themed-page-error.compone
import { ThemedPageInternalServerErrorComponent } from './page-internal-server-error/themed-page-internal-server-error.component';
import { ThemedPageNotFoundComponent } from './pagenotfound/themed-pagenotfound.component';
import { PROCESS_MODULE_PATH } from './process-page/process-page-routing.paths';
import { viewTrackerResolver } from './statistics/angulartics/dspace/view-tracker.resolver';
import { provideSubmissionState } from './submission/provide-submission-state';
import { SUGGESTION_MODULE_PATH } from './suggestions-page/suggestions-page-routing-paths';
@@ -63,9 +65,16 @@ export const APP_ROUTES: Route[] = [
path: 'home',
loadChildren: () => import('./home-page/home-page-routes')
.then((m) => m.ROUTES),
data: { showBreadcrumbs: false },
data: {
showBreadcrumbs: false,
dsoPath: 'site',
},
providers: [provideSuggestionNotificationsState()],
canActivate: [endUserAgreementCurrentUserGuard],
resolve: {
site: homePageResolver,
tracking: viewTrackerResolver,
},
},
{
path: 'community-list',

View File

@@ -11,6 +11,7 @@ import { ComcolSearchSectionComponent } from '../shared/comcol/sections/comcol-s
import { dsoEditMenuResolver } from '../shared/dso-page/dso-edit-menu.resolver';
import { LinkMenuItemModel } from '../shared/menu/menu-item/models/link.model';
import { MenuItemType } from '../shared/menu/menu-item-type.model';
import { viewTrackerResolver } from '../statistics/angulartics/dspace/view-tracker.resolver';
import { collectionPageResolver } from './collection-page.resolver';
import { collectionPageAdministratorGuard } from './collection-page-administrator.guard';
import {
@@ -84,6 +85,7 @@ export const ROUTES: Route[] = [
component: ThemedCollectionPageComponent,
resolve: {
menu: dsoEditMenuResolver,
tracking: viewTrackerResolver,
},
children: [
{

View File

@@ -3,7 +3,6 @@
*ngVar="(collectionRD$ | async) as collectionRD">
<div *ngIf="collectionRD?.hasSucceeded" @fadeInOut>
<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">
<header class="comcol-header mr-auto">
<!-- Collection Name -->

View File

@@ -50,7 +50,6 @@ import { ThemedLoadingComponent } from '../shared/loading/themed-loading.compone
import { ObjectCollectionComponent } from '../shared/object-collection/object-collection.component';
import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model';
import { VarDirective } from '../shared/utils/var.directive';
import { ViewTrackerComponent } from '../statistics/angulartics/dspace/view-tracker.component';
import { getCollectionPageRoute } from './collection-page-routing-paths';
@Component({
@@ -68,7 +67,6 @@ import { getCollectionPageRoute } from './collection-page-routing-paths';
NgIf,
ThemedLoadingComponent,
TranslateModule,
ViewTrackerComponent,
VarDirective,
AsyncPipe,
ComcolPageHeaderComponent,

View File

@@ -10,6 +10,7 @@ import { ComcolSearchSectionComponent } from '../shared/comcol/sections/comcol-s
import { dsoEditMenuResolver } from '../shared/dso-page/dso-edit-menu.resolver';
import { LinkMenuItemModel } from '../shared/menu/menu-item/models/link.model';
import { MenuItemType } from '../shared/menu/menu-item-type.model';
import { viewTrackerResolver } from '../statistics/angulartics/dspace/view-tracker.resolver';
import { communityPageResolver } from './community-page.resolver';
import { communityPageAdministratorGuard } from './community-page-administrator.guard';
import {
@@ -71,6 +72,7 @@ export const ROUTES: Route[] = [
component: ThemedCommunityPageComponent,
resolve: {
menu: dsoEditMenuResolver,
tracking: viewTrackerResolver,
},
children: [
{

View File

@@ -1,7 +1,6 @@
<div class="container" *ngVar="(communityRD$ | async) as communityRD">
<div class="community-page" *ngIf="communityRD?.hasSucceeded" @fadeInOut>
<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">
<header class="comcol-header mr-auto">
<!-- Community name -->

View File

@@ -41,7 +41,6 @@ import { hasValue } from '../shared/empty.util';
import { ErrorComponent } from '../shared/error/error.component';
import { ThemedLoadingComponent } from '../shared/loading/themed-loading.component';
import { VarDirective } from '../shared/utils/var.directive';
import { ViewTrackerComponent } from '../statistics/angulartics/dspace/view-tracker.component';
import { getCommunityPageRoute } from './community-page-routing-paths';
import { ThemedCollectionPageSubCollectionListComponent } from './sections/sub-com-col-section/sub-collection-list/themed-community-page-sub-collection-list.component';
import { ThemedCommunityPageSubCommunityListComponent } from './sections/sub-com-col-section/sub-community-list/themed-community-page-sub-community-list.component';
@@ -66,7 +65,6 @@ import { ThemedCommunityPageSubCommunityListComponent } from './sections/sub-com
ComcolPageLogoComponent,
ComcolPageHeaderComponent,
AsyncPipe,
ViewTrackerComponent,
VarDirective,
RouterOutlet,
RouterModule,

View File

@@ -2,7 +2,6 @@ import { Route } from '@angular/router';
import { LinkMenuItemModel } from '../shared/menu/menu-item/models/link.model';
import { MenuItemType } from '../shared/menu/menu-item-type.model';
import { homePageResolver } from './home-page.resolver';
import { ThemedHomePageComponent } from './themed-home-page.component';
export const ROUTES: Route[] = [
@@ -26,8 +25,5 @@ export const ROUTES: Route[] = [
}],
},
},
resolve: {
site: homePageResolver,
},
},
];

View File

@@ -14,9 +14,6 @@
<ds-suggestions-popup></ds-suggestions-popup>
<ng-template #homeContent>
<ng-container *ngIf="(site$ | async) as site">
<ds-view-tracker [object]="site"></ds-view-tracker>
</ng-container>
<ds-search-form [inPlaceSearch]="false"
[searchPlaceholder]="'home.search-form.placeholder' | translate">
</ds-search-form>

View File

@@ -23,7 +23,6 @@ import { SuggestionsPopupComponent } from '../notifications/suggestions-popup/su
import { ThemedConfigurationSearchPageComponent } from '../search-page/themed-configuration-search-page.component';
import { ThemedSearchFormComponent } from '../shared/search-form/themed-search-form.component';
import { PageWithSidebarComponent } from '../shared/sidebar/page-with-sidebar.component';
import { ViewTrackerComponent } from '../statistics/angulartics/dspace/view-tracker.component';
import { HomeCoarComponent } from './home-coar/home-coar.component';
import { ThemedHomeNewsComponent } from './home-news/themed-home-news.component';
import { RecentItemListComponent } from './recent-item-list/recent-item-list.component';
@@ -34,7 +33,7 @@ import { ThemedTopLevelCommunityListComponent } from './top-level-community-list
styleUrls: ['./home-page.component.scss'],
templateUrl: './home-page.component.html',
standalone: true,
imports: [ThemedHomeNewsComponent, NgTemplateOutlet, NgIf, ViewTrackerComponent, ThemedSearchFormComponent, ThemedTopLevelCommunityListComponent, RecentItemListComponent, AsyncPipe, TranslateModule, NgClass, SuggestionsPopupComponent, ThemedConfigurationSearchPageComponent, PageWithSidebarComponent, HomeCoarComponent],
imports: [ThemedHomeNewsComponent, NgTemplateOutlet, NgIf, ThemedSearchFormComponent, ThemedTopLevelCommunityListComponent, RecentItemListComponent, AsyncPipe, TranslateModule, NgClass, SuggestionsPopupComponent, ThemedConfigurationSearchPageComponent, PageWithSidebarComponent, HomeCoarComponent],
})
export class HomePageComponent implements OnInit {

View File

@@ -3,7 +3,6 @@
<div *ngIf="itemRD?.payload as item">
<ds-item-alerts [item]="item"></ds-item-alerts>
<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 class="d-flex flex-row">
<ds-item-page-title-field class="mr-auto" [item]="item"></ds-item-page-title-field>

View File

@@ -45,7 +45,7 @@ import { createPaginatedList } from '../../shared/testing/utils.test';
import { ThemeService } from '../../shared/theme-support/theme.service';
import { TruncatePipe } from '../../shared/utils/truncate.pipe';
import { VarDirective } from '../../shared/utils/var.directive';
import { ViewTrackerComponent } from '../../statistics/angulartics/dspace/view-tracker.component';
import { ViewTrackerResolverService } from '../../statistics/angulartics/dspace/view-tracker-resolver.service';
import { ThemedItemAlertsComponent } from '../alerts/themed-item-alerts.component';
import { CollectionsComponent } from '../field-components/collections/collections.component';
import { ThemedItemPageTitleFieldComponent } from '../simple/field-components/specific-field/title/themed-item-page-field.component';
@@ -162,7 +162,7 @@ describe('FullItemPageComponent', () => {
ThemedLoadingComponent,
ThemedItemPageTitleFieldComponent,
DsoEditMenuComponent,
ViewTrackerComponent,
ViewTrackerResolverService,
ThemedItemAlertsComponent,
CollectionsComponent,
ThemedFullFileSectionComponent,

View File

@@ -44,7 +44,6 @@ import { hasValue } from '../../shared/empty.util';
import { ErrorComponent } from '../../shared/error/error.component';
import { ThemedLoadingComponent } from '../../shared/loading/themed-loading.component';
import { VarDirective } from '../../shared/utils/var.directive';
import { ViewTrackerComponent } from '../../statistics/angulartics/dspace/view-tracker.component';
import { ThemedItemAlertsComponent } from '../alerts/themed-item-alerts.component';
import { CollectionsComponent } from '../field-components/collections/collections.component';
import { ThemedItemPageTitleFieldComponent } from '../simple/field-components/specific-field/title/themed-item-page-field.component';
@@ -79,7 +78,6 @@ import { ThemedFullFileSectionComponent } from './field-components/file-section/
ThemedItemPageTitleFieldComponent,
DsoEditMenuComponent,
ItemVersionsNoticeComponent,
ViewTrackerComponent,
ThemedItemAlertsComponent,
VarDirective,
],

View File

@@ -6,6 +6,7 @@ import { itemBreadcrumbResolver } from '../core/breadcrumbs/item-breadcrumb.reso
import { dsoEditMenuResolver } from '../shared/dso-page/dso-edit-menu.resolver';
import { LinkMenuItemModel } from '../shared/menu/menu-item/models/link.model';
import { MenuItemType } from '../shared/menu/menu-item-type.model';
import { viewTrackerResolver } from '../statistics/angulartics/dspace/view-tracker.resolver';
import { BitstreamRequestACopyPageComponent } from './bitstreams/request-a-copy/bitstream-request-a-copy-page.component';
import { UploadBitstreamComponent } from './bitstreams/upload/upload-bitstream.component';
import { ThemedFullItemPageComponent } from './full/themed-full-item-page.component';
@@ -36,6 +37,7 @@ export const ROUTES: Route[] = [
pathMatch: 'full',
resolve: {
menu: dsoEditMenuResolver,
tracking: viewTrackerResolver,
},
},
{
@@ -43,6 +45,7 @@ export const ROUTES: Route[] = [
component: ThemedFullItemPageComponent,
resolve: {
menu: dsoEditMenuResolver,
tracking: viewTrackerResolver,
},
},
{

View File

@@ -5,7 +5,6 @@
<ds-qa-event-notification [item]="item"></ds-qa-event-notification>
<ds-notify-requests-status [itemUuid]="item.uuid"></ds-notify-requests-status>
<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-item-versions class="mt-2" [item]="item" [displayActions]="false"></ds-item-versions>
</div>

View File

@@ -44,7 +44,7 @@ import {
import { ActivatedRouteStub } from '../../shared/testing/active-router.stub';
import { createPaginatedList } from '../../shared/testing/utils.test';
import { VarDirective } from '../../shared/utils/var.directive';
import { ViewTrackerComponent } from '../../statistics/angulartics/dspace/view-tracker.component';
import { ViewTrackerResolverService } from '../../statistics/angulartics/dspace/view-tracker-resolver.service';
import { ThemedItemAlertsComponent } from '../alerts/themed-item-alerts.component';
import { ItemVersionsComponent } from '../versions/item-versions.component';
import { ItemVersionsNoticeComponent } from '../versions/notice/item-versions-notice.component';
@@ -142,7 +142,7 @@ describe('ItemPageComponent', () => {
remove: { imports: [
ThemedItemAlertsComponent,
ItemVersionsNoticeComponent,
ViewTrackerComponent,
ViewTrackerResolverService,
ListableObjectComponentLoaderComponent,
ItemVersionsComponent,
ErrorComponent,

View File

@@ -48,7 +48,6 @@ import { ErrorComponent } from '../../shared/error/error.component';
import { ThemedLoadingComponent } from '../../shared/loading/themed-loading.component';
import { ListableObjectComponentLoaderComponent } from '../../shared/object-collection/shared/listable-object/listable-object-component-loader.component';
import { VarDirective } from '../../shared/utils/var.directive';
import { ViewTrackerComponent } from '../../statistics/angulartics/dspace/view-tracker.component';
import { ThemedItemAlertsComponent } from '../alerts/themed-item-alerts.component';
import { getItemPageRoute } from '../item-page-routing-paths';
import { ItemVersionsComponent } from '../versions/item-versions.component';
@@ -72,7 +71,6 @@ import { QaEventNotificationComponent } from './qa-event-notification/qa-event-n
VarDirective,
ThemedItemAlertsComponent,
ItemVersionsNoticeComponent,
ViewTrackerComponent,
ListableObjectComponentLoaderComponent,
ItemVersionsComponent,
ErrorComponent,

View File

@@ -0,0 +1,64 @@
import { Injectable } from '@angular/core';
import {
ActivatedRouteSnapshot,
ResolveEnd,
Router,
RouterStateSnapshot,
} from '@angular/router';
import { Angulartics2 } from 'angulartics2';
import { switchMap } from 'rxjs';
import {
filter,
take,
} from 'rxjs/operators';
import { ReferrerService } from '../../../core/services/referrer.service';
/**
* 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,63 +0,0 @@
import {
Component,
Input,
OnDestroy,
OnInit,
} from '@angular/core';
import { Angulartics2 } from 'angulartics2';
import { Subscription } from 'rxjs';
import { 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';
/**
* This component triggers a page view statistic
*/
@Component({
selector: 'ds-view-tracker',
styleUrls: ['./view-tracker.component.scss'],
templateUrl: './view-tracker.component.html',
standalone: true,
})
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

@@ -0,0 +1,16 @@
import { inject } from '@angular/core';
import {
ActivatedRouteSnapshot,
ResolveFn,
RouterStateSnapshot,
} from '@angular/router';
import { ViewTrackerResolverService } from './view-tracker-resolver.service';
export const viewTrackerResolver: ResolveFn<boolean> = (
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot,
viewTrackerResolverService: ViewTrackerResolverService = inject(ViewTrackerResolverService),
): boolean => {
return viewTrackerResolverService.resolve(route, state);
};

View File

@@ -24,7 +24,6 @@ import { ErrorComponent } from '../../../../app/shared/error/error.component';
import { ThemedLoadingComponent } from '../../../../app/shared/loading/themed-loading.component';
import { ObjectCollectionComponent } from '../../../../app/shared/object-collection/object-collection.component';
import { VarDirective } from '../../../../app/shared/utils/var.directive';
import { ViewTrackerComponent } from '../../../../app/statistics/angulartics/dspace/view-tracker.component';
@Component({
selector: 'ds-themed-collection-page',
@@ -44,7 +43,6 @@ import { ViewTrackerComponent } from '../../../../app/statistics/angulartics/dsp
NgIf,
ThemedLoadingComponent,
TranslateModule,
ViewTrackerComponent,
VarDirective,
AsyncPipe,
ComcolPageHeaderComponent,

View File

@@ -25,7 +25,6 @@ import { DsoEditMenuComponent } from '../../../../app/shared/dso-page/dso-edit-m
import { ErrorComponent } from '../../../../app/shared/error/error.component';
import { ThemedLoadingComponent } from '../../../../app/shared/loading/themed-loading.component';
import { VarDirective } from '../../../../app/shared/utils/var.directive';
import { ViewTrackerComponent } from '../../../../app/statistics/angulartics/dspace/view-tracker.component';
@Component({
selector: 'ds-themed-community-page',
@@ -50,7 +49,6 @@ import { ViewTrackerComponent } from '../../../../app/statistics/angulartics/dsp
ComcolPageLogoComponent,
ComcolPageHeaderComponent,
AsyncPipe,
ViewTrackerComponent,
VarDirective,
RouterOutlet,
RouterModule,

View File

@@ -16,7 +16,6 @@ import { SuggestionsPopupComponent } from '../../../../app/notifications/suggest
import { ThemedConfigurationSearchPageComponent } from '../../../../app/search-page/themed-configuration-search-page.component';
import { ThemedSearchFormComponent } from '../../../../app/shared/search-form/themed-search-form.component';
import { PageWithSidebarComponent } from '../../../../app/shared/sidebar/page-with-sidebar.component';
import { ViewTrackerComponent } from '../../../../app/statistics/angulartics/dspace/view-tracker.component';
@Component({
selector: 'ds-themed-home-page',
@@ -25,7 +24,7 @@ import { ViewTrackerComponent } from '../../../../app/statistics/angulartics/dsp
// templateUrl: './home-page.component.html'
templateUrl: '../../../../app/home-page/home-page.component.html',
standalone: true,
imports: [ThemedHomeNewsComponent, NgTemplateOutlet, NgIf, ViewTrackerComponent, ThemedSearchFormComponent, ThemedTopLevelCommunityListComponent, RecentItemListComponent, AsyncPipe, TranslateModule, NgClass, SuggestionsPopupComponent, ThemedConfigurationSearchPageComponent, PageWithSidebarComponent, HomeCoarComponent],
imports: [ThemedHomeNewsComponent, NgTemplateOutlet, NgIf, ThemedSearchFormComponent, ThemedTopLevelCommunityListComponent, RecentItemListComponent, AsyncPipe, TranslateModule, NgClass, SuggestionsPopupComponent, ThemedConfigurationSearchPageComponent, PageWithSidebarComponent, HomeCoarComponent],
})
export class HomePageComponent extends BaseComponent {

View File

@@ -23,7 +23,6 @@ import { DsoEditMenuComponent } from '../../../../../app/shared/dso-page/dso-edi
import { ErrorComponent } from '../../../../../app/shared/error/error.component';
import { ThemedLoadingComponent } from '../../../../../app/shared/loading/themed-loading.component';
import { VarDirective } from '../../../../../app/shared/utils/var.directive';
import { ViewTrackerComponent } from '../../../../../app/statistics/angulartics/dspace/view-tracker.component';
/**
* This component renders a full item page.
@@ -54,7 +53,6 @@ import { ViewTrackerComponent } from '../../../../../app/statistics/angulartics/
ThemedItemPageTitleFieldComponent,
DsoEditMenuComponent,
ItemVersionsNoticeComponent,
ViewTrackerComponent,
ThemedItemAlertsComponent,
VarDirective,
],

View File

@@ -19,7 +19,6 @@ import { ErrorComponent } from '../../../../../app/shared/error/error.component'
import { ThemedLoadingComponent } from '../../../../../app/shared/loading/themed-loading.component';
import { ListableObjectComponentLoaderComponent } from '../../../../../app/shared/object-collection/shared/listable-object/listable-object-component-loader.component';
import { VarDirective } from '../../../../../app/shared/utils/var.directive';
import { ViewTrackerComponent } from '../../../../../app/statistics/angulartics/dspace/view-tracker.component';
/**
* This component renders a simple item page.
@@ -39,7 +38,6 @@ import { ViewTrackerComponent } from '../../../../../app/statistics/angulartics/
VarDirective,
ThemedItemAlertsComponent,
ItemVersionsNoticeComponent,
ViewTrackerComponent,
ListableObjectComponentLoaderComponent,
ItemVersionsComponent,
ErrorComponent,