Skip to content

Commit

Permalink
MARP-1307 Adapt mp prod for measurement with matomo (#225)
Browse files Browse the repository at this point in the history
Co-authored-by: Hoang Vu Huy <[email protected]>
  • Loading branch information
vhhoang-axonivy and Hoang Vu Huy authored Nov 7, 2024
1 parent 83bcdb0 commit 666e737
Show file tree
Hide file tree
Showing 22 changed files with 297 additions and 20 deletions.
46 changes: 46 additions & 0 deletions marketplace-build/config/matomo/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: matomo-prod

services:
matomo-db:
image: mysql:9.1.0
container_name: matomo-db
restart: always
volumes:
- matomo-data:/var/lib/mysql:Z
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_DATABASE=${MYSQL_DATABASE}
- MYSQL_USER=${MYSQL_USER}
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
ports:
- 3310:3306
env_file:
- ./matomo-db.env

matomo-app:
image: matomo:fpm-alpine
container_name: matomo-app
restart: always
links:
- matomo-db
volumes:
- matomo:/var/www/html:z
environment:
- MATOMO_DATABASE_HOST=matomo-db
- PHP_MEMORY_LIMIT=2048M
env_file:
- ./matomo-db.env

matomo-web:
image: nginx:alpine
container_name: matomo-web
restart: always
volumes:
- matomo:/var/www/html:z,ro
- ./matomo.conf:/etc/nginx/conf.d/default.conf:z,ro
ports:
- 8085:80

volumes:
matomo-data:
matomo:
8 changes: 8 additions & 0 deletions marketplace-build/config/matomo/matomo-db.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
MYSQL_ROOT_PASSWORD=
MYSQL_DATABASE=matomo
MYSQL_USER=matomo
MYSQL_PASSWORD=
MATOMO_DATABASE_ADAPTER=mysql
MATOMO_DATABASE_TABLES_PREFIX=matomo_
MATOMO_DATABASE_USERNAME=matomo
MATOMO_DATABASE_DBNAME=matomo
69 changes: 69 additions & 0 deletions marketplace-build/config/matomo/matomo.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
upstream php-handler {
server matomo-app:9000;
}

server {
listen 80;

add_header Referrer-Policy origin; # make sure outgoing links don't show the URL to the Matomo instance
root /var/www/html; # replace with path to your matomo instance
index index.php;
try_files $uri $uri/ =404;

## only allow accessing the following php files
location ~ ^/(index|matomo|piwik|js/index|plugins/HeatmapSessionRecording/configs).php {
# regex to split $uri to $fastcgi_script_name and $fastcgi_path
fastcgi_split_path_info ^(.+\.php)(/.+)$;

# Check that the PHP script exists before passing it
try_files $fastcgi_script_name =404;

include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param HTTP_PROXY ""; # prohibit httpoxy: https://httpoxy.org/
fastcgi_pass php-handler;
}

## deny access to all other .php files
location ~* ^.+\.php$ {
deny all;
return 403;
}

## disable all access to the following directories
location ~ /(config|tmp|core|lang) {
deny all;
return 403; # replace with 404 to not show these directories exist
}
location ~ /\.ht {
deny all;
return 403;
}

location ~ js/container_.*_preview\.js$ {
expires off;
add_header Cache-Control 'private, no-cache, no-store';
}

location ~ \.(gif|ico|jpg|png|svg|js|css|htm|html|mp3|mp4|wav|ogg|avi|ttf|eot|woff|woff2|json)$ {
allow all;
## Cache images,CSS,JS and webfonts for an hour
## Increasing the duration may improve the load-time, but may cause old files to show after an Matomo upgrade
expires 1h;
add_header Pragma public;
add_header Cache-Control "public";
}

location ~ /(libs|vendor|plugins|misc/user) {
deny all;
return 403;
}

## properly display textfiles in root directory
location ~/(.*\.md|LEGALNOTICE|LICENSE) {
default_type text/plain;
}
}

# vim: filetype=nginx
14 changes: 14 additions & 0 deletions marketplace-ui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions marketplace-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"marked": "^12.0.0",
"ngx-cookie-service": "^18.0.0",
"ngx-markdown": "^18.0.0",
"ngx-matomo-client": "^6.3.1",
"ngxtension": "^3.5.5",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
Expand Down
8 changes: 8 additions & 0 deletions marketplace-ui/src/app/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { MARKED_OPTIONS, MarkdownModule } from 'ngx-markdown';
import { markedOptionsFactory } from './core/configs/markdown.config';
import { httpLoaderFactory } from './core/configs/translate.config';
import { apiInterceptor } from './core/interceptors/api.interceptor';
import { provideMatomo, withRouter } from 'ngx-matomo-client';
import { environment } from '../environments/environment';

const scrollConfig: InMemoryScrollingOptions = {
scrollPositionRestoration: 'disabled',
Expand All @@ -21,6 +23,12 @@ export const appConfig: ApplicationConfig = {
provideZoneChangeDetection({ eventCoalescing: true }),
provideRouter(routes, inMemoryScrollingFeature),
provideHttpClient(withFetch(), withInterceptors([apiInterceptor])),
provideMatomo({
siteId: environment.matomoSiteId,
trackerUrl: environment.matomoTrackerUrl,
},
withRouter(),
),
importProvidersFrom(
TranslateModule.forRoot({
loader: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { of } from 'rxjs';
import { ProductComponent } from '../../modules/product/product.component';
import { DESIGNER_COOKIE_VARIABLE } from '../../shared/constants/common.constant';
import { apiInterceptor } from './api.interceptor';
import { MatomoTestingModule } from 'ngx-matomo-client/testing';

describe('AuthInterceptor', () => {
let productComponent: ProductComponent;
Expand All @@ -16,7 +17,11 @@ describe('AuthInterceptor', () => {

beforeEach(() => {
TestBed.configureTestingModule({
imports: [ProductComponent, TranslateModule.forRoot()],
imports: [
ProductComponent,
TranslateModule.forRoot(),
MatomoTestingModule.forRoot()
],
providers: [
provideHttpClient(withInterceptors([apiInterceptor])),
HttpTestingController,
Expand Down
7 changes: 6 additions & 1 deletion marketplace-ui/src/app/modules/home/home.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,19 @@ import {
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { ActivatedRoute } from '@angular/router';
import { of } from 'rxjs';
import { MatomoTestingModule } from 'ngx-matomo-client/testing';

describe('HomeComponent', () => {
let component: HomeComponent;
let fixture: ComponentFixture<HomeComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [HomeComponent, TranslateModule.forRoot()],
imports: [
HomeComponent,
TranslateModule.forRoot(),
MatomoTestingModule.forRoot()
],
providers: [
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
@case (ProductDetailActionType.STANDARD) {
<div class="install-download-button-container gap-2 w-100 d-flex">
<button
id="install-button"
name="Install button"
#installButton
[matomoClickCategory]="MatomoCategory.BUTTON"
[matomoClickAction]="MatomoAction.CLICK"
[matomoClickName]="installButton.name + ' - ' + getTrackingEnvironmentBasedOnActionType()"
[lang]="languageService.selectedLanguage()"
class="btn btn__install flex-grow-1 me-lg-2"
data-bs-toggle="tooltip"
Expand All @@ -24,7 +30,12 @@
</button>
@if (!isMavenDropins) {
<button
id="download-button"
name="Download button"
#artifactDownloadButton
[matomoClickCategory]="MatomoCategory.BUTTON"
[matomoClickAction]="MatomoAction.CLICK"
[matomoClickName]="artifactDownloadButton.name + ' - ' + getTrackingEnvironmentBasedOnActionType()"
[lang]="languageService.selectedLanguage()"
class="btn btn__download btn-secondary primary-bg flex-grow-1"
type="button"
Expand Down Expand Up @@ -108,7 +119,13 @@
[metaDataJsonUrl]="metaDataJsonUrl()"
(itemSelected)="onSelectVersionInDesigner($event.value)">
</app-common-dropdown>
<button [lang]="languageService.selectedLanguage()"
<button id="install-button"
name="Install button"
#installButton
[matomoClickCategory]="MatomoCategory.BUTTON"
[matomoClickAction]="MatomoAction.CLICK"
[matomoClickName]="installButton.name + ' - ' + getTrackingEnvironmentBasedOnActionType()"
[lang]="languageService.selectedLanguage()"
class="btn btn__install flex-grow-1 install-designer-button m-0 col-4" id="install-button"
(click)="onUpdateInstallationCountForDesigner()" onClick="function installInDesigner() {
const selectedItemElement = document.querySelector('.install-designer-dropdown');
Expand All @@ -123,7 +140,14 @@
</div>
}
@case (ProductDetailActionType.CUSTOM_SOLUTION) {
<button [lang]="languageService.selectedLanguage()"
<button
id="contact-us-button"
name="Contact us button"
#contactUsButton
[matomoClickCategory]="MatomoCategory.BUTTON"
[matomoClickAction]="MatomoAction.CLICK"
[matomoClickName]="contactUsButton.name + ' - ' + getTrackingEnvironmentBasedOnActionType()"
[lang]="languageService.selectedLanguage()"
class="btn row btn_contact-us"
(click)="onNavigateToContactPage()"
[ngClass]="themeService.isDarkMode() ? 'btn-light' : 'btn-primary'">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ import { CookieService } from 'ngx-cookie-service';
import { ActivatedRoute, provideRouter, Router } from '@angular/router';
import { CommonUtils } from '../../../../shared/utils/common.utils';
import { ROUTER } from '../../../../shared/constants/router.constant';
import { MatomoConfiguration, MatomoModule, MatomoRouterModule } from 'ngx-matomo-client';
import { MatomoTestingModule } from 'ngx-matomo-client/testing';
import { ProductDetailActionType } from '../../../../shared/enums/product-detail-action-type';
import { MATOMO_TRACKING_ENVIRONMENT } from '../../../../shared/constants/matomo.constant';

class MockElementRef implements ElementRef {
nativeElement = {
Expand Down Expand Up @@ -38,7 +42,11 @@ describe('ProductDetailVersionActionComponent', () => {
});

TestBed.configureTestingModule({
imports: [ProductDetailVersionActionComponent, TranslateModule.forRoot()],
imports: [
ProductDetailVersionActionComponent,
TranslateModule.forRoot(),
MatomoTestingModule.forRoot()
],
providers: [
TranslateService,
CookieService,
Expand Down Expand Up @@ -354,4 +362,25 @@ describe('ProductDetailVersionActionComponent', () => {
expect(productServiceMock.sendRequestToGetProductVersionsForDesigner).toHaveBeenCalledWith(productId);
expect(component.versions()).toEqual([]);
});

it('should return the correct tracking environment based on the action type', () => {
const testCases = [
{ actionType: ProductDetailActionType.STANDARD, expected: MATOMO_TRACKING_ENVIRONMENT.standard },
{ actionType: ProductDetailActionType.DESIGNER_ENV, expected: MATOMO_TRACKING_ENVIRONMENT.designerEnv },
{ actionType: ProductDetailActionType.CUSTOM_SOLUTION, expected: MATOMO_TRACKING_ENVIRONMENT.customSolution },
];

testCases.forEach(({ actionType, expected }) => {
component.actionType = actionType;

const result = component.getTrackingEnvironmentBasedOnActionType();
expect(result).toBe(expected);
});
});

it('should return empty environment when action type is default', () => {
const result = component.getTrackingEnvironmentBasedOnActionType();

expect(result).toBe('');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ import { CookieService } from 'ngx-cookie-service';
import { CommonUtils } from '../../../../shared/utils/common.utils';
import { ActivatedRoute, Router } from '@angular/router';
import { ROUTER } from '../../../../shared/constants/router.constant';
import { MatomoTrackClickDirective } from 'ngx-matomo-client';
import { MatomoCategory, MatomoAction } from '../../../../shared/enums/matomo-tracking.enum';
import { MATOMO_TRACKING_ENVIRONMENT } from '../../../../shared/constants/matomo.constant';

const showDevVersionCookieName = 'showDevVersions';

Expand All @@ -43,7 +46,8 @@ const showDevVersionCookieName = 'showDevVersions';
TranslateModule,
FormsModule,
CommonDropdownComponent,
LoadingSpinnerComponent
LoadingSpinnerComponent,
MatomoTrackClickDirective
],
templateUrl: './product-detail-version-action.component.html',
styleUrl: './product-detail-version-action.component.scss'
Expand All @@ -56,6 +60,10 @@ export class ProductDetailVersionActionComponent implements AfterViewInit {
@Input() actionType!: ProductDetailActionType;
@Input() product!: ProductDetail;
protected ProductDetailActionType = ProductDetailActionType;
protected MatomoCategory = MatomoCategory;
protected MatomoAction = MatomoAction;
trackedEnvironmentForMatomo = ''

selectedVersion = model<string>('');
versions: WritableSignal<string[]> = signal([]);
versionDropdown: Signal<ItemDropdown[]> = computed(() => {
Expand Down Expand Up @@ -249,4 +257,17 @@ export class ProductDetailVersionActionComponent implements AfterViewInit {
}
window.focus();
}

getTrackingEnvironmentBasedOnActionType() {
switch (this.actionType) {
case ProductDetailActionType.STANDARD:
return MATOMO_TRACKING_ENVIRONMENT.standard;
case ProductDetailActionType.DESIGNER_ENV:
return MATOMO_TRACKING_ENVIRONMENT.designerEnv;
case ProductDetailActionType.CUSTOM_SOLUTION:
return MATOMO_TRACKING_ENVIRONMENT.customSolution;
default:
return '';
}
}
}
Loading

0 comments on commit 666e737

Please sign in to comment.