Skip to content

Commit

Permalink
Development: Migrate admin metrics Angular code to new best practices
Browse files Browse the repository at this point in the history
  • Loading branch information
krusche committed Sep 8, 2024
1 parent aaa6837 commit 83fd408
Show file tree
Hide file tree
Showing 27 changed files with 1,334 additions and 416 deletions.
1,196 changes: 1,051 additions & 145 deletions package-lock.json

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"monaco-editor": "0.51.0",
"ngx-infinite-scroll": "18.0.0",
"ngx-webstorage": "18.0.0",
"ngxtension": "4.0.0",
"papaparse": "5.4.1",
"pdfjs-dist": "4.6.82",
"posthog-js": "1.160.3",
Expand Down Expand Up @@ -88,13 +89,13 @@
"d3-transition": "^3.0.1"
},
"@typescript-eslint/utils": {
"eslint": "^9.9.0"
"eslint": "^9.10.0"
},
"braces": "3.0.3",
"critters": "0.0.24",
"debug": "4.3.6",
"eslint-plugin-deprecation": {
"eslint": "^9.9.0"
"eslint": "^9.10.0"
},
"eslint-plugin-jest": {
"@typescript-eslint/eslint-plugin": "^8.4.0"
Expand Down Expand Up @@ -138,7 +139,7 @@
"@types/uuid": "10.0.0",
"@typescript-eslint/eslint-plugin": "8.4.0",
"@typescript-eslint/parser": "8.4.0",
"eslint": "9.9.1",
"eslint": "9.10.0",
"eslint-config-prettier": "9.1.0",
"eslint-plugin-deprecation": "3.0.0",
"eslint-plugin-jest": "28.8.3",
Expand Down
2 changes: 0 additions & 2 deletions src/main/webapp/app/admin/admin.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import { OrganizationManagementComponent } from './organization-management/organ
import { OrganizationManagementDetailComponent } from './organization-management/organization-management-detail.component';
import { OrganizationManagementUpdateComponent } from './organization-management/organization-management-update.component';
import { ArtemisDataTableModule } from 'app/shared/data-table/data-table.module';
import { MetricsModule } from 'app/admin/metrics/metrics.module';
import { ArtemisChartsModule } from 'app/shared/chart/artemis-charts.module';
import { MatChipsModule } from '@angular/material/chips';
import { MatAutocompleteModule } from '@angular/material/autocomplete';
Expand Down Expand Up @@ -57,7 +56,6 @@ const ENTITY_STATES = [...adminState];
FormDateTimePickerModule,
NgxDatatableModule,
ArtemisDataTableModule,
MetricsModule,
ArtemisChartsModule,
MatChipsModule,
MatAutocompleteModule,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<h4 jhiTranslate="metrics.jvm.memory.title"></h4>
@if (!updating && jvmMemoryMetrics) {
@if (!updating() && jvmMemoryMetrics()) {
<div>
@for (entry of jvmMemoryMetrics | keyvalue; track entry) {
@for (entry of jvmMemoryMetrics() | keyvalue; track entry) {
<div>
@if (entry.value.max !== -1) {
<span>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
import { Component, Input } from '@angular/core';
import { ChangeDetectionStrategy, Component, input } from '@angular/core';

import { JvmMetrics } from 'app/admin/metrics/metrics.model';
import { TranslateDirective } from 'app/shared/language/translate.directive';
import { NgbProgressbar } from '@ng-bootstrap/ng-bootstrap';
import { DecimalPipe, KeyValuePipe } from '@angular/common';

@Component({
selector: 'jhi-jvm-memory',
templateUrl: './jvm-memory.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [TranslateDirective, NgbProgressbar, DecimalPipe, KeyValuePipe],
})
export class JvmMemoryComponent {
/**
* object containing all jvm memory metrics
*/
@Input() jvmMemoryMetrics?: { [key: string]: JvmMetrics };
jvmMemoryMetrics = input.required<{
[key: string]: JvmMetrics;
}>();

/**
* boolean field saying if the metrics are in the process of being updated
*/
@Input() updating?: boolean;
updating = input<boolean>(false);
}
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
<h4 jhiTranslate="metrics.jvm.threads.title"></h4>

<span><span jhiTranslate="metrics.jvm.threads.runnable"></span> {{ threadStats.threadDumpRunnable }}</span>
<span><span jhiTranslate="metrics.jvm.threads.runnable"></span> {{ threadStats().runnable }}</span>

<ngb-progressbar [value]="threadStats.threadDumpRunnable" [max]="threadStats.threadDumpAll" [striped]="true" [animated]="false" type="success">
<span>{{ (threadStats.threadDumpRunnable * 100) / threadStats.threadDumpAll | number: '1.0-0' }}%</span>
<ngb-progressbar [value]="threadStats().runnable" [max]="threadStats().all" [striped]="true" [animated]="false" type="success">
<span>{{ (threadStats().runnable * 100) / threadStats().all | number: '1.0-0' }}%</span>
</ngb-progressbar>

<span><span jhiTranslate="metrics.jvm.threads.timedwaiting"></span> ({{ threadStats.threadDumpTimedWaiting }})</span>
<span><span jhiTranslate="metrics.jvm.threads.timedwaiting"></span> ({{ threadStats().timedWaiting }})</span>

<ngb-progressbar [value]="threadStats.threadDumpTimedWaiting" [max]="threadStats.threadDumpAll" [striped]="true" [animated]="false" type="warning">
<span>{{ (threadStats.threadDumpTimedWaiting * 100) / threadStats.threadDumpAll | number: '1.0-0' }}%</span>
<ngb-progressbar [value]="threadStats().timedWaiting" [max]="threadStats().all" [striped]="true" [animated]="false" type="warning">
<span>{{ (threadStats().timedWaiting * 100) / threadStats().all | number: '1.0-0' }}%</span>
</ngb-progressbar>

<span><span jhiTranslate="metrics.jvm.threads.waiting"></span> ({{ threadStats.threadDumpWaiting }})</span>
<span><span jhiTranslate="metrics.jvm.threads.waiting"></span> ({{ threadStats().waiting }})</span>

<ngb-progressbar [value]="threadStats.threadDumpWaiting" [max]="threadStats.threadDumpAll" [striped]="true" [animated]="false" type="warning">
<span>{{ (threadStats.threadDumpWaiting * 100) / threadStats.threadDumpAll | number: '1.0-0' }}%</span>
<ngb-progressbar [value]="threadStats().waiting" [max]="threadStats().all" [striped]="true" [animated]="false" type="warning">
<span>{{ (threadStats().waiting * 100) / threadStats().all | number: '1.0-0' }}%</span>
</ngb-progressbar>

<span><span jhiTranslate="metrics.jvm.threads.blocked"></span> ({{ threadStats.threadDumpBlocked }})</span>
<span><span jhiTranslate="metrics.jvm.threads.blocked"></span> ({{ threadStats().blocked }})</span>

<ngb-progressbar [value]="threadStats.threadDumpBlocked" [max]="threadStats.threadDumpAll" [striped]="true" [animated]="false" type="success">
<span>{{ (threadStats.threadDumpBlocked * 100) / threadStats.threadDumpAll | number: '1.0-0' }}%</span>
<ngb-progressbar [value]="threadStats().blocked" [max]="threadStats().all" [striped]="true" [animated]="false" type="success">
<span>{{ (threadStats().blocked * 100) / threadStats().all | number: '1.0-0' }}%</span>
</ngb-progressbar>

<div>Total: {{ threadStats.threadDumpAll }}</div>
<div>Total: {{ threadStats().all }}</div>

<button class="hand btn btn-primary btn-sm" (click)="open()" data-toggle="modal" data-target="#threadDump">
<span>Expand</span>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,52 +1,60 @@
import { Component, Input } from '@angular/core';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, effect, inject, input, signal } from '@angular/core';
import { NgbModal, NgbProgressbar } from '@ng-bootstrap/ng-bootstrap';

import { Thread, ThreadState } from 'app/admin/metrics/metrics.model';
import { MetricsModalThreadsComponent } from '../metrics-modal-threads/metrics-modal-threads.component';
import { TranslateDirective } from 'app/shared/language/translate.directive';
import { DecimalPipe } from '@angular/common';

@Component({
selector: 'jhi-jvm-threads',
templateUrl: './jvm-threads.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [TranslateDirective, NgbProgressbar, DecimalPipe],
})
export class JvmThreadsComponent {
threadStats = {
threadDumpAll: 0,
threadDumpRunnable: 0,
threadDumpTimedWaiting: 0,
threadDumpWaiting: 0,
threadDumpBlocked: 0,
};

@Input()
set threads(threads: Thread[] | undefined) {
this._threads = threads;

threads?.forEach((thread) => {
if (thread.threadState === ThreadState.Runnable) {
this.threadStats.threadDumpRunnable += 1;
} else if (thread.threadState === ThreadState.Waiting) {
this.threadStats.threadDumpWaiting += 1;
} else if (thread.threadState === ThreadState.TimedWaiting) {
this.threadStats.threadDumpTimedWaiting += 1;
} else if (thread.threadState === ThreadState.Blocked) {
this.threadStats.threadDumpBlocked += 1;
}
});
threadStats = signal({
all: 0,
runnable: 0,
timedWaiting: 0,
waiting: 0,
blocked: 0,
});

this.threadStats.threadDumpAll =
this.threadStats.threadDumpRunnable + this.threadStats.threadDumpWaiting + this.threadStats.threadDumpTimedWaiting + this.threadStats.threadDumpBlocked;
}
private changeDetector = inject(ChangeDetectorRef);
private modalService = inject(NgbModal);

threads = input<Thread[]>([]);

get threads(): Thread[] | undefined {
return this._threads;
constructor() {
effect(() => this.computeThreadStats());
}

private _threads: Thread[] | undefined;
private computeThreadStats() {
this.threads().forEach((thread) => {
switch (thread.threadState) {
case ThreadState.Runnable:
this.threadStats().runnable += 1;
break;
case ThreadState.Waiting:
this.threadStats().waiting += 1;
break;
case ThreadState.TimedWaiting:
this.threadStats().timedWaiting += 1;
break;
case ThreadState.Blocked:
this.threadStats().blocked += 1;
break;
}
});

constructor(private modalService: NgbModal) {}
this.threadStats().all = this.threadStats().runnable + this.threadStats().waiting + this.threadStats().timedWaiting + this.threadStats().blocked;
this.changeDetector.markForCheck();
}

open(): void {
const modalRef = this.modalService.open(MetricsModalThreadsComponent, { size: 'xl' });
modalRef.componentInstance.threads = this.threads;
modalRef.componentInstance.threads = this.threads();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<h3 id="cacheMetrics" jhiTranslate="metrics.cache.title"></h3>
@if (!updating && cacheMetrics) {
@if (!updating() && cacheMetrics()) {
<div class="table-responsive">
<table class="table table-striped" aria-describedby="cacheMetrics">
<thead>
Expand All @@ -16,7 +16,7 @@ <h3 id="cacheMetrics" jhiTranslate="metrics.cache.title"></h3>
</tr>
</thead>
<tbody>
@for (entry of cacheMetrics | keyvalue; track entry) {
@for (entry of cacheMetrics() | keyvalue; track entry) {
<tr>
<td>{{ entry.key }}</td>
<td class="text-right">{{ entry.value['cache.gets.hit'] }}</td>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { ChangeDetectionStrategy, Component, input } from '@angular/core';
import { CacheMetrics } from 'app/admin/metrics/metrics.model';
import { filterNaN } from 'app/core/util/operators';
import { TranslateDirective } from 'app/shared/language/translate.directive';
import { DecimalPipe, KeyValuePipe } from '@angular/common';

@Component({
selector: 'jhi-metrics-cache',
templateUrl: './metrics-cache.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [TranslateDirective, DecimalPipe, KeyValuePipe],
})
export class MetricsCacheComponent {
/**
* object containing all cache related metrics
*/
@Input() cacheMetrics?: { [key: string]: CacheMetrics };
cacheMetrics = input.required<{
[key: string]: CacheMetrics;
}>();

/**
* boolean field saying if the metrics are in the process of being updated
*/
@Input() updating?: boolean;
updating = input<boolean>(false);

filterNaN = (input: number): number => filterNaN(input);
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<h3 id="datasourceMetrics" jhiTranslate="metrics.datasource.title"></h3>
@if (!updating && datasourceMetrics) {
@if (!updating()) {
<div class="table-responsive">
<table class="table table-striped" aria-describedby="datasourceMetrics">
<thead>
<tr>
<th scope="col">
<span jhiTranslate="metrics.datasource.usage"></span> (active: {{ datasourceMetrics.active.value }}, min: {{ datasourceMetrics.min.value }}, max:
{{ datasourceMetrics.max.value }}, idle: {{ datasourceMetrics.idle.value }})
<span jhiTranslate="metrics.datasource.usage"></span> (active: {{ datasourceMetrics().active.value }}, min: {{ datasourceMetrics().min.value }}, max:
{{ datasourceMetrics().max.value }}, idle: {{ datasourceMetrics().idle.value }})
</th>
<th scope="col" class="text-right" jhiTranslate="metrics.datasource.count"></th>
<th scope="col" class="text-right" jhiTranslate="metrics.datasource.mean"></th>
Expand All @@ -21,36 +21,36 @@ <h3 id="datasourceMetrics" jhiTranslate="metrics.datasource.title"></h3>
<tbody>
<tr>
<td>Acquire</td>
<td class="text-right">{{ datasourceMetrics.acquire.count }}</td>
<td class="text-right">{{ filterNaN(datasourceMetrics.acquire.mean) | number: '1.0-2' }}</td>
<td class="text-right">{{ datasourceMetrics.acquire['0.0'] | number: '1.0-3' }}</td>
<td class="text-right">{{ datasourceMetrics.acquire['0.5'] | number: '1.0-3' }}</td>
<td class="text-right">{{ datasourceMetrics.acquire['0.75'] | number: '1.0-3' }}</td>
<td class="text-right">{{ datasourceMetrics.acquire['0.95'] | number: '1.0-3' }}</td>
<td class="text-right">{{ datasourceMetrics.acquire['0.99'] | number: '1.0-3' }}</td>
<td class="text-right">{{ filterNaN(datasourceMetrics.acquire.max) | number: '1.0-2' }}</td>
<td class="text-right">{{ datasourceMetrics().acquire.count }}</td>
<td class="text-right">{{ filterNaN(datasourceMetrics().acquire.mean) | number: '1.0-2' }}</td>
<td class="text-right">{{ datasourceMetrics().acquire['0.0'] | number: '1.0-3' }}</td>
<td class="text-right">{{ datasourceMetrics().acquire['0.5'] | number: '1.0-3' }}</td>
<td class="text-right">{{ datasourceMetrics().acquire['0.75'] | number: '1.0-3' }}</td>
<td class="text-right">{{ datasourceMetrics().acquire['0.95'] | number: '1.0-3' }}</td>
<td class="text-right">{{ datasourceMetrics().acquire['0.99'] | number: '1.0-3' }}</td>
<td class="text-right">{{ filterNaN(datasourceMetrics().acquire.max) | number: '1.0-2' }}</td>
</tr>
<tr>
<td>Creation</td>
<td class="text-right">{{ datasourceMetrics.creation.count }}</td>
<td class="text-right">{{ filterNaN(datasourceMetrics.creation.mean) | number: '1.0-2' }}</td>
<td class="text-right">{{ datasourceMetrics.creation['0.0'] | number: '1.0-3' }}</td>
<td class="text-right">{{ datasourceMetrics.creation['0.5'] | number: '1.0-3' }}</td>
<td class="text-right">{{ datasourceMetrics.creation['0.75'] | number: '1.0-3' }}</td>
<td class="text-right">{{ datasourceMetrics.creation['0.95'] | number: '1.0-3' }}</td>
<td class="text-right">{{ datasourceMetrics.creation['0.99'] | number: '1.0-3' }}</td>
<td class="text-right">{{ filterNaN(datasourceMetrics.creation.max) | number: '1.0-2' }}</td>
<td class="text-right">{{ datasourceMetrics().creation.count }}</td>
<td class="text-right">{{ filterNaN(datasourceMetrics().creation.mean) | number: '1.0-2' }}</td>
<td class="text-right">{{ datasourceMetrics().creation['0.0'] | number: '1.0-3' }}</td>
<td class="text-right">{{ datasourceMetrics().creation['0.5'] | number: '1.0-3' }}</td>
<td class="text-right">{{ datasourceMetrics().creation['0.75'] | number: '1.0-3' }}</td>
<td class="text-right">{{ datasourceMetrics().creation['0.95'] | number: '1.0-3' }}</td>
<td class="text-right">{{ datasourceMetrics().creation['0.99'] | number: '1.0-3' }}</td>
<td class="text-right">{{ filterNaN(datasourceMetrics().creation.max) | number: '1.0-2' }}</td>
</tr>
<tr>
<td>Usage</td>
<td class="text-right">{{ datasourceMetrics.usage.count }}</td>
<td class="text-right">{{ filterNaN(datasourceMetrics.usage.mean) | number: '1.0-2' }}</td>
<td class="text-right">{{ datasourceMetrics.usage['0.0'] | number: '1.0-3' }}</td>
<td class="text-right">{{ datasourceMetrics.usage['0.5'] | number: '1.0-3' }}</td>
<td class="text-right">{{ datasourceMetrics.usage['0.75'] | number: '1.0-3' }}</td>
<td class="text-right">{{ datasourceMetrics.usage['0.95'] | number: '1.0-3' }}</td>
<td class="text-right">{{ datasourceMetrics.usage['0.99'] | number: '1.0-3' }}</td>
<td class="text-right">{{ filterNaN(datasourceMetrics.usage.max) | number: '1.0-2' }}</td>
<td class="text-right">{{ datasourceMetrics().usage.count }}</td>
<td class="text-right">{{ filterNaN(datasourceMetrics().usage.mean) | number: '1.0-2' }}</td>
<td class="text-right">{{ datasourceMetrics().usage['0.0'] | number: '1.0-3' }}</td>
<td class="text-right">{{ datasourceMetrics().usage['0.5'] | number: '1.0-3' }}</td>
<td class="text-right">{{ datasourceMetrics().usage['0.75'] | number: '1.0-3' }}</td>
<td class="text-right">{{ datasourceMetrics().usage['0.95'] | number: '1.0-3' }}</td>
<td class="text-right">{{ datasourceMetrics().usage['0.99'] | number: '1.0-3' }}</td>
<td class="text-right">{{ filterNaN(datasourceMetrics().usage.max) | number: '1.0-2' }}</td>
</tr>
</tbody>
</table>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { ChangeDetectionStrategy, Component, input } from '@angular/core';
import { Databases } from 'app/admin/metrics/metrics.model';
import { filterNaN } from 'app/core/util/operators';
import { TranslateDirective } from 'app/shared/language/translate.directive';
import { DecimalPipe } from '@angular/common';

@Component({
selector: 'jhi-metrics-datasource',
templateUrl: './metrics-datasource.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [TranslateDirective, DecimalPipe],
})
export class MetricsDatasourceComponent {
/**
* object containing all datasource related metrics
*/
@Input() datasourceMetrics?: Databases;
datasourceMetrics = input.required<Databases>();

/**
* boolean field saying if the metrics are in the process of being updated
*/
@Input() updating?: boolean;
updating = input<boolean>(false);

filterNaN = (input: number): number => filterNaN(input);
}
Loading

0 comments on commit 83fd408

Please sign in to comment.