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 @@

- + 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",
Module{{ element.fileName }} + + content_copy + {{ element.fileName }} + +