diff --git a/apps/frontend/src/app/app.config.ts b/apps/frontend/src/app/app.config.ts
index 96ca378..e1bc640 100644
--- a/apps/frontend/src/app/app.config.ts
+++ b/apps/frontend/src/app/app.config.ts
@@ -1,3 +1,4 @@
+import { ClipboardModule } from '@angular/cdk/clipboard';
import { provideHttpClient } from '@angular/common/http';
import {
ApplicationConfig,
@@ -5,6 +6,7 @@ import {
provideZoneChangeDetection,
} from '@angular/core';
import { MatDialogModule } from '@angular/material/dialog';
+import { MatSnackBarModule } from '@angular/material/snack-bar';
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
import { provideRouter, withComponentInputBinding } from '@angular/router';
@@ -19,5 +21,7 @@ export const appConfig: ApplicationConfig = {
provideErrorHandler(AppErrorHandler),
provideAnimationsAsync(),
importProvidersFrom(MatDialogModule),
+ importProvidersFrom(MatSnackBarModule),
+ importProvidersFrom(ClipboardModule),
],
};
diff --git a/apps/frontend/src/app/features/hotspot/hotspot-detail/hotspot-detail.component.css b/apps/frontend/src/app/features/hotspot/hotspot-detail/hotspot-detail.component.css
index 17bacc4..ef02619 100644
--- a/apps/frontend/src/app/features/hotspot/hotspot-detail/hotspot-detail.component.css
+++ b/apps/frontend/src/app/features/hotspot/hotspot-detail/hotspot-detail.component.css
@@ -2,3 +2,15 @@
margin-left: 15px;
margin-top: 10px;
}
+
+.copy-icon {
+ font-size: 16px;
+ padding: 0px;
+ margin: 0px;
+ line-height: 1;
+ vertical-align: middle;
+}
+
+.copy-link {
+ cursor: pointer;
+}
diff --git a/apps/frontend/src/app/features/hotspot/hotspot-detail/hotspot-detail.component.html b/apps/frontend/src/app/features/hotspot/hotspot-detail/hotspot-detail.component.html
index 95837cf..1027c3f 100644
--- a/apps/frontend/src/app/features/hotspot/hotspot-detail/hotspot-detail.component.html
+++ b/apps/frontend/src/app/features/hotspot/hotspot-detail/hotspot-detail.component.html
@@ -16,7 +16,12 @@
Module |
- {{ element.fileName }} |
+
+
+ content_copy
+ {{ element.fileName }}
+
+ |
diff --git a/apps/frontend/src/app/features/hotspot/hotspot-detail/hotspot-detail.component.ts b/apps/frontend/src/app/features/hotspot/hotspot-detail/hotspot-detail.component.ts
index c5d60c8..f89c1ab 100644
--- a/apps/frontend/src/app/features/hotspot/hotspot-detail/hotspot-detail.component.ts
+++ b/apps/frontend/src/app/features/hotspot/hotspot-detail/hotspot-detail.component.ts
@@ -1,3 +1,4 @@
+import { Clipboard } from '@angular/cdk/clipboard';
import { CommonModule } from '@angular/common';
import {
Component,
@@ -8,8 +9,10 @@ import {
viewChild,
} from '@angular/core';
import { MatDialogModule } from '@angular/material/dialog';
+import { MatIconModule } from '@angular/material/icon';
import { MatPaginator } from '@angular/material/paginator';
import { MatProgressBar } from '@angular/material/progress-bar';
+import { MatSnackBar } from '@angular/material/snack-bar';
import { MatSortModule } from '@angular/material/sort';
import { MatTableDataSource, MatTableModule } from '@angular/material/table';
@@ -27,6 +30,7 @@ import { HotspotStore } from '../hotspot.store';
MatPaginator,
MatProgressBar,
MatDialogModule,
+ MatIconModule,
],
templateUrl: './hotspot-detail.component.html',
styleUrl: './hotspot-detail.component.css',
@@ -34,6 +38,9 @@ import { HotspotStore } from '../hotspot.store';
export class HotspotDetailComponent {
private hotspotStore = inject(HotspotStore);
+ private clipboard = inject(Clipboard);
+ private snackBar = inject(MatSnackBar);
+
module = this.hotspotStore.filter.module;
color = computed(() => getScoreTypeColor(this.hotspotStore.scoreType()));
@@ -67,6 +74,20 @@ export class HotspotDetailComponent {
}
});
}
+
+ copy(fileName: string) {
+ if (this.clipboard.copy(fileName)) {
+ this.snackBar.open('Filename copied to clipboard', 'Ok', {
+ duration: 3000,
+ });
+ } else {
+ console.log('Error writing to clipboard');
+ this.snackBar.open(
+ 'Writing the filename to the clipboard did not work',
+ 'Ok'
+ );
+ }
+ }
}
function formatHotspots(
diff --git a/apps/frontend/src/app/features/hotspot/hotspot.component.css b/apps/frontend/src/app/features/hotspot/hotspot.component.css
index c3d208a..ba2cae4 100644
--- a/apps/frontend/src/app/features/hotspot/hotspot.component.css
+++ b/apps/frontend/src/app/features/hotspot/hotspot.component.css
@@ -55,3 +55,8 @@
.min-score {
width: 120px;
}
+
+.docu-link {
+ margin-right: 15px;
+ margin-left: 0px;
+}
diff --git a/apps/frontend/src/app/features/hotspot/hotspot.component.html b/apps/frontend/src/app/features/hotspot/hotspot.component.html
index 77cd598..f77dacc 100644
--- a/apps/frontend/src/app/features/hotspot/hotspot.component.html
+++ b/apps/frontend/src/app/features/hotspot/hotspot.component.html
@@ -1,6 +1,15 @@
-
Min. Score: (%)
+
+ Filter
+
+
+
Tolerance
@@ -19,7 +28,7 @@
diff --git a/apps/frontend/src/app/features/hotspot/hotspot.component.ts b/apps/frontend/src/app/features/hotspot/hotspot.component.ts
index 1d5ec04..b931f87 100644
--- a/apps/frontend/src/app/features/hotspot/hotspot.component.ts
+++ b/apps/frontend/src/app/features/hotspot/hotspot.component.ts
@@ -1,6 +1,7 @@
import { Component, computed, inject } from '@angular/core';
import { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';
import { FormsModule } from '@angular/forms';
+import { MatButtonModule } from '@angular/material/button';
import { MatDialog, MatDialogModule } from '@angular/material/dialog';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatIconModule } from '@angular/material/icon';
@@ -62,6 +63,7 @@ interface Option {
MatIconModule,
MatTooltipModule,
TreeMapComponent,
+ MatButtonModule,
],
templateUrl: './hotspot.component.html',
styleUrl: './hotspot.component.css',
@@ -156,7 +158,7 @@ export class HotspotComponent {
0,
result.warningBoundary,
result.hotspotBoundary,
- result.maxScore,
+ result.maxScore + 1,
];
return range;
}
diff --git a/package-lock.json b/package-lock.json
index 01c4e4c..40c5bc1 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -6577,6 +6577,18 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
+ "node_modules/@nx/js/node_modules/babel-plugin-macros": {
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz",
+ "integrity": "sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.7.2",
+ "cosmiconfig": "^6.0.0",
+ "resolve": "^1.12.0"
+ }
+ },
"node_modules/@nx/js/node_modules/chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
@@ -6627,6 +6639,23 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@nx/js/node_modules/cosmiconfig": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz",
+ "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/parse-json": "^4.0.0",
+ "import-fresh": "^3.1.0",
+ "parse-json": "^5.0.0",
+ "path-type": "^4.0.0",
+ "yaml": "^1.7.2"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/@nx/js/node_modules/fast-glob": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz",
@@ -7128,6 +7157,18 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
+ "node_modules/@nx/linter/node_modules/babel-plugin-macros": {
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz",
+ "integrity": "sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.7.2",
+ "cosmiconfig": "^6.0.0",
+ "resolve": "^1.12.0"
+ }
+ },
"node_modules/@nx/linter/node_modules/chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
@@ -7178,6 +7219,23 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@nx/linter/node_modules/cosmiconfig": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz",
+ "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/parse-json": "^4.0.0",
+ "import-fresh": "^3.1.0",
+ "parse-json": "^5.0.0",
+ "path-type": "^4.0.0",
+ "yaml": "^1.7.2"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/@nx/linter/node_modules/define-lazy-prop": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
@@ -11579,32 +11637,40 @@
}
},
"node_modules/babel-plugin-macros": {
- "version": "2.8.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz",
- "integrity": "sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz",
+ "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==",
"dev": true,
"license": "MIT",
+ "optional": true,
+ "peer": true,
"dependencies": {
- "@babel/runtime": "^7.7.2",
- "cosmiconfig": "^6.0.0",
- "resolve": "^1.12.0"
+ "@babel/runtime": "^7.12.5",
+ "cosmiconfig": "^7.0.0",
+ "resolve": "^1.19.0"
+ },
+ "engines": {
+ "node": ">=10",
+ "npm": ">=6"
}
},
"node_modules/babel-plugin-macros/node_modules/cosmiconfig": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz",
- "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==",
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
+ "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==",
"dev": true,
"license": "MIT",
+ "optional": true,
+ "peer": true,
"dependencies": {
"@types/parse-json": "^4.0.0",
- "import-fresh": "^3.1.0",
+ "import-fresh": "^3.2.1",
"parse-json": "^5.0.0",
"path-type": "^4.0.0",
- "yaml": "^1.7.2"
+ "yaml": "^1.10.0"
},
"engines": {
- "node": ">=8"
+ "node": ">=10"
}
},
"node_modules/babel-plugin-polyfill-corejs2": {
@@ -27212,7 +27278,6 @@
"version": "5.5.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz",
"integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==",
- "dev": true,
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",