mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 01:54:15 +00:00
[CST-18964] add matomo integration
This commit is contained in:
13
package-lock.json
generated
13
package-lock.json
generated
@@ -66,6 +66,7 @@
|
|||||||
"ng2-file-upload": "5.0.0",
|
"ng2-file-upload": "5.0.0",
|
||||||
"ng2-nouislider": "^2.0.0",
|
"ng2-nouislider": "^2.0.0",
|
||||||
"ngx-infinite-scroll": "^16.0.0",
|
"ngx-infinite-scroll": "^16.0.0",
|
||||||
|
"ngx-matomo-client": "^6.4.1",
|
||||||
"ngx-pagination": "6.0.3",
|
"ngx-pagination": "6.0.3",
|
||||||
"ngx-skeleton-loader": "^9.0.0",
|
"ngx-skeleton-loader": "^9.0.0",
|
||||||
"ngx-ui-switch": "^14.1.0",
|
"ngx-ui-switch": "^14.1.0",
|
||||||
@@ -16935,6 +16936,18 @@
|
|||||||
"@angular/forms": ">=10.0.0"
|
"@angular/forms": ">=10.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ngx-matomo-client": {
|
||||||
|
"version": "6.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ngx-matomo-client/-/ngx-matomo-client-6.4.1.tgz",
|
||||||
|
"integrity": "sha512-GRriCGW0ULCg9oSZw3ule+o9esELVVJTJ0Z99/zYKGjlyrrHLn5a1e0GSdgICubo59gP1cg9NwsOC0BH7oio9A==",
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.3.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@angular/common": "^17.0.0 || ^18.0.0",
|
||||||
|
"@angular/core": "^17.0.0 || ^18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ngx-pagination": {
|
"node_modules/ngx-pagination": {
|
||||||
"version": "6.0.3",
|
"version": "6.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/ngx-pagination/-/ngx-pagination-6.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/ngx-pagination/-/ngx-pagination-6.0.3.tgz",
|
||||||
|
@@ -153,6 +153,7 @@
|
|||||||
"ng2-file-upload": "5.0.0",
|
"ng2-file-upload": "5.0.0",
|
||||||
"ng2-nouislider": "^2.0.0",
|
"ng2-nouislider": "^2.0.0",
|
||||||
"ngx-infinite-scroll": "^16.0.0",
|
"ngx-infinite-scroll": "^16.0.0",
|
||||||
|
"ngx-matomo-client": "^6.4.1",
|
||||||
"ngx-pagination": "6.0.3",
|
"ngx-pagination": "6.0.3",
|
||||||
"ngx-skeleton-loader": "^9.0.0",
|
"ngx-skeleton-loader": "^9.0.0",
|
||||||
"ngx-ui-switch": "^14.1.0",
|
"ngx-ui-switch": "^14.1.0",
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
/* eslint-disable max-classes-per-file */
|
/* eslint-disable max-classes-per-file */
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { Angulartics2 } from 'angulartics2';
|
import { Angulartics2 } from 'angulartics2';
|
||||||
|
import { MatomoTracker } from 'ngx-matomo-client';
|
||||||
import {
|
import {
|
||||||
BehaviorSubject,
|
BehaviorSubject,
|
||||||
combineLatest as observableCombineLatest,
|
combineLatest as observableCombineLatest,
|
||||||
@@ -112,6 +113,7 @@ export class SearchService {
|
|||||||
private paginationService: PaginationService,
|
private paginationService: PaginationService,
|
||||||
private searchConfigurationService: SearchConfigurationService,
|
private searchConfigurationService: SearchConfigurationService,
|
||||||
private angulartics2: Angulartics2,
|
private angulartics2: Angulartics2,
|
||||||
|
private matomoTracker: MatomoTracker,
|
||||||
) {
|
) {
|
||||||
this.searchDataService = new SearchDataService();
|
this.searchDataService = new SearchDataService();
|
||||||
}
|
}
|
||||||
@@ -367,7 +369,7 @@ export class SearchService {
|
|||||||
const appliedFilter = appliedFilters[i];
|
const appliedFilter = appliedFilters[i];
|
||||||
filters.push(appliedFilter);
|
filters.push(appliedFilter);
|
||||||
}
|
}
|
||||||
this.angulartics2.eventTrack.next({
|
const searchTrackObject = {
|
||||||
action: 'search',
|
action: 'search',
|
||||||
properties: {
|
properties: {
|
||||||
searchOptions: config,
|
searchOptions: config,
|
||||||
@@ -384,7 +386,10 @@ export class SearchService {
|
|||||||
filters: filters,
|
filters: filters,
|
||||||
clickedObject,
|
clickedObject,
|
||||||
},
|
},
|
||||||
});
|
};
|
||||||
|
|
||||||
|
this.matomoTracker.trackSiteSearch(config.query, config.scope, searchQueryResponse.pageInfo.totalElements, searchTrackObject);
|
||||||
|
this.angulartics2.eventTrack.next(searchTrackObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -39,6 +39,7 @@ import { OrejimeService } from './orejime.service';
|
|||||||
import {
|
import {
|
||||||
ANONYMOUS_STORAGE_NAME_OREJIME,
|
ANONYMOUS_STORAGE_NAME_OREJIME,
|
||||||
getOrejimeConfiguration,
|
getOrejimeConfiguration,
|
||||||
|
MATOMO_OREJIME_KEY,
|
||||||
} from './orejime-configuration';
|
} from './orejime-configuration';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -133,8 +134,10 @@ export class BrowserOrejimeService extends OrejimeService {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
const appsToHide$: Observable<string[]> = observableCombineLatest([hideGoogleAnalytics$, hideRegistrationVerification$]).pipe(
|
const hideMatomo$ = observableOf(!(environment.matomo?.trackerUrl && environment.matomo?.siteId));
|
||||||
map(([hideGoogleAnalytics, hideRegistrationVerification]) => {
|
|
||||||
|
const appsToHide$: Observable<string[]> = observableCombineLatest([hideGoogleAnalytics$, hideRegistrationVerification$, hideMatomo$]).pipe(
|
||||||
|
map(([hideGoogleAnalytics, hideRegistrationVerification, hideMatomo]) => {
|
||||||
const appsToHideArray: string[] = [];
|
const appsToHideArray: string[] = [];
|
||||||
if (hideGoogleAnalytics) {
|
if (hideGoogleAnalytics) {
|
||||||
appsToHideArray.push(this.GOOGLE_ANALYTICS_SERVICE_NAME);
|
appsToHideArray.push(this.GOOGLE_ANALYTICS_SERVICE_NAME);
|
||||||
@@ -142,6 +145,9 @@ export class BrowserOrejimeService extends OrejimeService {
|
|||||||
if (hideRegistrationVerification) {
|
if (hideRegistrationVerification) {
|
||||||
appsToHideArray.push(CAPTCHA_NAME);
|
appsToHideArray.push(CAPTCHA_NAME);
|
||||||
}
|
}
|
||||||
|
if (hideMatomo) {
|
||||||
|
appsToHideArray.push(MATOMO_OREJIME_KEY);
|
||||||
|
}
|
||||||
return appsToHideArray;
|
return appsToHideArray;
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
@@ -19,6 +19,10 @@ export const ANONYMOUS_STORAGE_NAME_OREJIME = 'orejime-anonymous';
|
|||||||
|
|
||||||
export const GOOGLE_ANALYTICS_OREJIME_KEY = 'google-analytics';
|
export const GOOGLE_ANALYTICS_OREJIME_KEY = 'google-analytics';
|
||||||
|
|
||||||
|
export const MATOMO_OREJIME_KEY = 'matomo';
|
||||||
|
|
||||||
|
export const MATOMO_COOKIE = 'dsMatomo';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Orejime configuration
|
* Orejime configuration
|
||||||
* For more information see https://github.com/empreinte-digitale/orejime
|
* For more information see https://github.com/empreinte-digitale/orejime
|
||||||
@@ -134,6 +138,17 @@ export function getOrejimeConfiguration(_window: NativeWindowRef): any {
|
|||||||
HAS_AGREED_END_USER,
|
HAS_AGREED_END_USER,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: MATOMO_OREJIME_KEY,
|
||||||
|
purposes: ['statistical'],
|
||||||
|
required: false,
|
||||||
|
cookies: [
|
||||||
|
MATOMO_COOKIE,
|
||||||
|
],
|
||||||
|
callback: (consent: boolean) => {
|
||||||
|
_window?.nativeWindow.changeMatomoConsent(consent);
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: GOOGLE_ANALYTICS_OREJIME_KEY,
|
name: GOOGLE_ANALYTICS_OREJIME_KEY,
|
||||||
purposes: ['statistical'],
|
purposes: ['statistical'],
|
||||||
|
16
src/app/statistics/matomo.service.spec.ts
Normal file
16
src/app/statistics/matomo.service.spec.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { MatomoService } from './matomo.service';
|
||||||
|
|
||||||
|
describe('MatomoService', () => {
|
||||||
|
let service: MatomoService;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({});
|
||||||
|
service = TestBed.inject(MatomoService);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
52
src/app/statistics/matomo.service.ts
Normal file
52
src/app/statistics/matomo.service.ts
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
import {
|
||||||
|
inject,
|
||||||
|
Injectable,
|
||||||
|
} from '@angular/core';
|
||||||
|
import {
|
||||||
|
MatomoInitializerService,
|
||||||
|
MatomoTracker,
|
||||||
|
} from 'ngx-matomo-client';
|
||||||
|
|
||||||
|
import { environment } from '../../environments/environment';
|
||||||
|
import { NativeWindowService } from '../core/services/window.service';
|
||||||
|
import { OrejimeService } from '../shared/cookies/orejime.service';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root',
|
||||||
|
})
|
||||||
|
export class MatomoService {
|
||||||
|
|
||||||
|
matomoInitializer = inject(MatomoInitializerService);
|
||||||
|
matomoTracker = inject(MatomoTracker);
|
||||||
|
orejimeService = inject(OrejimeService);
|
||||||
|
_window = inject(NativeWindowService);
|
||||||
|
|
||||||
|
init() {
|
||||||
|
if (this._window.nativeWindow) {
|
||||||
|
this._window.nativeWindow.changeMatomoConsent = this.changeMatomoConsent;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (environment.production) {
|
||||||
|
const preferences$ = this.orejimeService.getSavedPreferences();
|
||||||
|
|
||||||
|
preferences$.subscribe(preferences => {
|
||||||
|
this.changeMatomoConsent(preferences.matomo);
|
||||||
|
|
||||||
|
if (environment.matomo?.siteId && environment.matomo?.trackerUrl) {
|
||||||
|
this.matomoInitializer.initializeTracker({
|
||||||
|
siteId: environment.matomo.siteId,
|
||||||
|
trackerUrl: environment.matomo.trackerUrl,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
changeMatomoConsent = (consent: boolean) => {
|
||||||
|
if (consent) {
|
||||||
|
this.matomoTracker.setConsentGiven();
|
||||||
|
} else {
|
||||||
|
this.matomoTracker.forgetConsentGiven();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
3
src/app/statistics/mock-matomo-tracker.ts
Normal file
3
src/app/statistics/mock-matomo-tracker.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export class MockMatomoTracker {
|
||||||
|
trackSiteSearch = () => {};
|
||||||
|
}
|
@@ -1630,6 +1630,10 @@
|
|||||||
|
|
||||||
"cookies.consent.app.description.google-recaptcha": "We use google reCAPTCHA service during registration and password recovery",
|
"cookies.consent.app.description.google-recaptcha": "We use google reCAPTCHA service during registration and password recovery",
|
||||||
|
|
||||||
|
"cookies.consent.app.title.matomo": "Matomo",
|
||||||
|
|
||||||
|
"cookies.consent.app.description.matomo": "Allows us to track statistical data",
|
||||||
|
|
||||||
"cookies.consent.purpose.functional": "Functional",
|
"cookies.consent.purpose.functional": "Functional",
|
||||||
|
|
||||||
"cookies.consent.purpose.statistical": "Statistical",
|
"cookies.consent.purpose.statistical": "Statistical",
|
||||||
|
@@ -2029,6 +2029,13 @@
|
|||||||
"cookies.consent.app.description.google-recaptcha": "Utilizziamo il servizio Google reCAPTCHA nelle fasi di registrazione e recupero password",
|
"cookies.consent.app.description.google-recaptcha": "Utilizziamo il servizio Google reCAPTCHA nelle fasi di registrazione e recupero password",
|
||||||
|
|
||||||
|
|
||||||
|
// "cookies.consent.app.title.matomo": "Matomo",
|
||||||
|
"cookies.consent.app.title.matomo": "Matomo",
|
||||||
|
|
||||||
|
// "cookies.consent.app.description.matomo": "Allows us to track statistical data",
|
||||||
|
"cookies.consent.app.description.matomo": "Ci permette di tracciare i dati statistici",
|
||||||
|
|
||||||
|
|
||||||
// "cookies.consent.purpose.functional": "Functional",
|
// "cookies.consent.purpose.functional": "Functional",
|
||||||
"cookies.consent.purpose.functional": "Funzionale",
|
"cookies.consent.purpose.functional": "Funzionale",
|
||||||
|
|
||||||
|
@@ -24,6 +24,7 @@ import { InfoConfig } from './info-config.interface';
|
|||||||
import { ItemConfig } from './item-config.interface';
|
import { ItemConfig } from './item-config.interface';
|
||||||
import { LangConfig } from './lang-config.interface';
|
import { LangConfig } from './lang-config.interface';
|
||||||
import { MarkdownConfig } from './markdown-config.interface';
|
import { MarkdownConfig } from './markdown-config.interface';
|
||||||
|
import { MatomoConfig } from './matomo-config.interface';
|
||||||
import { MediaViewerConfig } from './media-viewer-config.interface';
|
import { MediaViewerConfig } from './media-viewer-config.interface';
|
||||||
import { INotificationBoardOptions } from './notifications-config.interfaces';
|
import { INotificationBoardOptions } from './notifications-config.interfaces';
|
||||||
import { QualityAssuranceConfig } from './quality-assurance.config';
|
import { QualityAssuranceConfig } from './quality-assurance.config';
|
||||||
@@ -66,6 +67,7 @@ interface AppConfig extends Config {
|
|||||||
search: SearchConfig;
|
search: SearchConfig;
|
||||||
notifyMetrics: AdminNotifyMetricsRow[];
|
notifyMetrics: AdminNotifyMetricsRow[];
|
||||||
liveRegion: LiveRegionConfig;
|
liveRegion: LiveRegionConfig;
|
||||||
|
matomo?: MatomoConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -19,6 +19,7 @@ import { InfoConfig } from './info-config.interface';
|
|||||||
import { ItemConfig } from './item-config.interface';
|
import { ItemConfig } from './item-config.interface';
|
||||||
import { LangConfig } from './lang-config.interface';
|
import { LangConfig } from './lang-config.interface';
|
||||||
import { MarkdownConfig } from './markdown-config.interface';
|
import { MarkdownConfig } from './markdown-config.interface';
|
||||||
|
import { MatomoConfig } from './matomo-config.interface';
|
||||||
import { MediaViewerConfig } from './media-viewer-config.interface';
|
import { MediaViewerConfig } from './media-viewer-config.interface';
|
||||||
import { INotificationBoardOptions } from './notifications-config.interfaces';
|
import { INotificationBoardOptions } from './notifications-config.interfaces';
|
||||||
import { QualityAssuranceConfig } from './quality-assurance.config';
|
import { QualityAssuranceConfig } from './quality-assurance.config';
|
||||||
@@ -599,4 +600,6 @@ export class DefaultAppConfig implements AppConfig {
|
|||||||
messageTimeOutDurationMs: 30000,
|
messageTimeOutDurationMs: 30000,
|
||||||
isVisible: false,
|
isVisible: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
matomo: MatomoConfig = {};
|
||||||
}
|
}
|
||||||
|
9
src/config/matomo-config.interface.ts
Normal file
9
src/config/matomo-config.interface.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import { Config } from './config.interface';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration interface for Matomo tracking
|
||||||
|
*/
|
||||||
|
export interface MatomoConfig extends Config {
|
||||||
|
trackerUrl?: string;
|
||||||
|
siteId?: string;
|
||||||
|
}
|
@@ -29,6 +29,11 @@ import {
|
|||||||
Angulartics2GoogleTagManager,
|
Angulartics2GoogleTagManager,
|
||||||
Angulartics2RouterlessModule,
|
Angulartics2RouterlessModule,
|
||||||
} from 'angulartics2';
|
} from 'angulartics2';
|
||||||
|
import {
|
||||||
|
provideMatomo,
|
||||||
|
withRouteData,
|
||||||
|
withRouter,
|
||||||
|
} from 'ngx-matomo-client';
|
||||||
|
|
||||||
import { commonAppConfig } from '../../app/app.config';
|
import { commonAppConfig } from '../../app/app.config';
|
||||||
import { storeModuleConfig } from '../../app/app.reducer';
|
import { storeModuleConfig } from '../../app/app.reducer';
|
||||||
@@ -157,5 +162,12 @@ export const browserAppConfig: ApplicationConfig = mergeApplicationConfig({
|
|||||||
provide: MathService,
|
provide: MathService,
|
||||||
useClass: ClientMathService,
|
useClass: ClientMathService,
|
||||||
},
|
},
|
||||||
|
provideMatomo(
|
||||||
|
{
|
||||||
|
mode: 'deferred',
|
||||||
|
},
|
||||||
|
withRouter(),
|
||||||
|
withRouteData(),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
}, commonAppConfig);
|
}, commonAppConfig);
|
||||||
|
@@ -45,6 +45,7 @@ import { MenuService } from '../../app/shared/menu/menu.service';
|
|||||||
import { ThemeService } from '../../app/shared/theme-support/theme.service';
|
import { ThemeService } from '../../app/shared/theme-support/theme.service';
|
||||||
import { Angulartics2DSpace } from '../../app/statistics/angulartics/dspace-provider';
|
import { Angulartics2DSpace } from '../../app/statistics/angulartics/dspace-provider';
|
||||||
import { GoogleAnalyticsService } from '../../app/statistics/google-analytics.service';
|
import { GoogleAnalyticsService } from '../../app/statistics/google-analytics.service';
|
||||||
|
import { MatomoService } from '../../app/statistics/matomo.service';
|
||||||
import {
|
import {
|
||||||
StoreAction,
|
StoreAction,
|
||||||
StoreActionTypes,
|
StoreActionTypes,
|
||||||
@@ -85,6 +86,7 @@ export class BrowserInitService extends InitService {
|
|||||||
protected router: Router,
|
protected router: Router,
|
||||||
private requestService: RequestService,
|
private requestService: RequestService,
|
||||||
private halService: HALEndpointService,
|
private halService: HALEndpointService,
|
||||||
|
private matomoService: MatomoService,
|
||||||
|
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
@@ -124,6 +126,7 @@ export class BrowserInitService extends InitService {
|
|||||||
this.initI18n();
|
this.initI18n();
|
||||||
this.initAngulartics();
|
this.initAngulartics();
|
||||||
this.initGoogleAnalytics();
|
this.initGoogleAnalytics();
|
||||||
|
this.initMatomo();
|
||||||
this.initRouteListeners();
|
this.initRouteListeners();
|
||||||
this.themeService.listenForThemeChanges(true);
|
this.themeService.listenForThemeChanges(true);
|
||||||
this.trackAuthTokenExpiration();
|
this.trackAuthTokenExpiration();
|
||||||
@@ -173,6 +176,10 @@ export class BrowserInitService extends InitService {
|
|||||||
this.googleAnalyticsService.addTrackingIdToPage();
|
this.googleAnalyticsService.addTrackingIdToPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected initMatomo(): void {
|
||||||
|
this.matomoService.init();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* During an external authentication flow invalidate the
|
* During an external authentication flow invalidate the
|
||||||
* data in the cache. This allows the app to fetch fresh content.
|
* data in the cache. This allows the app to fetch fresh content.
|
||||||
|
@@ -28,6 +28,7 @@ import {
|
|||||||
Angulartics2GoogleAnalytics,
|
Angulartics2GoogleAnalytics,
|
||||||
Angulartics2GoogleGlobalSiteTag,
|
Angulartics2GoogleGlobalSiteTag,
|
||||||
} from 'angulartics2';
|
} from 'angulartics2';
|
||||||
|
import { MatomoTracker } from 'ngx-matomo-client';
|
||||||
|
|
||||||
import { commonAppConfig } from '../../app/app.config';
|
import { commonAppConfig } from '../../app/app.config';
|
||||||
import { storeModuleConfig } from '../../app/app.reducer';
|
import { storeModuleConfig } from '../../app/app.reducer';
|
||||||
@@ -55,6 +56,7 @@ import { XSRFService } from '../../app/core/xsrf/xsrf.service';
|
|||||||
import { AngularticsProviderMock } from '../../app/shared/mocks/angulartics-provider.service.mock';
|
import { AngularticsProviderMock } from '../../app/shared/mocks/angulartics-provider.service.mock';
|
||||||
import { Angulartics2Mock } from '../../app/shared/mocks/angulartics2.service.mock';
|
import { Angulartics2Mock } from '../../app/shared/mocks/angulartics2.service.mock';
|
||||||
import { Angulartics2DSpace } from '../../app/statistics/angulartics/dspace-provider';
|
import { Angulartics2DSpace } from '../../app/statistics/angulartics/dspace-provider';
|
||||||
|
import { MockMatomoTracker } from '../../app/statistics/mock-matomo-tracker';
|
||||||
import { ServerSubmissionService } from '../../app/submission/server-submission.service';
|
import { ServerSubmissionService } from '../../app/submission/server-submission.service';
|
||||||
import { SubmissionService } from '../../app/submission/submission.service';
|
import { SubmissionService } from '../../app/submission/submission.service';
|
||||||
import { TranslateServerLoader } from '../../ngx-translate-loaders/translate-server.loader';
|
import { TranslateServerLoader } from '../../ngx-translate-loaders/translate-server.loader';
|
||||||
@@ -144,5 +146,9 @@ export const serverAppConfig: ApplicationConfig = mergeApplicationConfig({
|
|||||||
provide: MathService,
|
provide: MathService,
|
||||||
useClass: ServerMathService,
|
useClass: ServerMathService,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
provide: MatomoTracker,
|
||||||
|
useClass: MockMatomoTracker,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
}, commonAppConfig);
|
}, commonAppConfig);
|
||||||
|
Reference in New Issue
Block a user