statistics
This commit is contained in:
17
idp_client/package-lock.json
generated
17
idp_client/package-lock.json
generated
@@ -19,6 +19,7 @@
|
||||
"@angular/router": "^18.0.0",
|
||||
"@ngneat/overview": "^6.0.0",
|
||||
"@ngxpert/hot-toast": "^3.0.0",
|
||||
"chart.js": "^4.4.4",
|
||||
"rxjs": "~7.8.0",
|
||||
"tslib": "^2.3.0",
|
||||
"zone.js": "~0.14.3"
|
||||
@@ -3146,6 +3147,11 @@
|
||||
"tslib": "2"
|
||||
}
|
||||
},
|
||||
"node_modules/@kurkle/color": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz",
|
||||
"integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw=="
|
||||
},
|
||||
"node_modules/@leichtgewicht/ip-codec": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz",
|
||||
@@ -5150,6 +5156,17 @@
|
||||
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/chart.js": {
|
||||
"version": "4.4.4",
|
||||
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.4.tgz",
|
||||
"integrity": "sha512-emICKGBABnxhMjUjlYRR12PmOXhJ2eJjEHL2/dZlWjxRAZT1D8xplLFq5M0tMQK8ja+wBS/tuVEJB5C6r7VxJA==",
|
||||
"dependencies": {
|
||||
"@kurkle/color": "^0.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"pnpm": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/chokidar": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
"@angular/router": "^18.0.0",
|
||||
"@ngneat/overview": "^6.0.0",
|
||||
"@ngxpert/hot-toast": "^3.0.0",
|
||||
"chart.js": "^4.4.4",
|
||||
"rxjs": "~7.8.0",
|
||||
"tslib": "^2.3.0",
|
||||
"zone.js": "~0.14.3"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<div class="header flex-row">
|
||||
<span>{{ client.clientName }}x</span>
|
||||
<span>{{ client.clientName }}</span>
|
||||
<div class="flex-row">
|
||||
<div class="flex-row" style=" gap: 0;"><mat-icon>shield_person</mat-icon><div style="line-height: 8px;">{{ client.admins.length }}</div></div>
|
||||
<div class="flex-row" style=" gap: 0;"><mat-icon>link</mat-icon><div style="line-height: 8px;">{{ client.redirectUris.length }}</div></div>
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Component, inject } from '@angular/core';
|
||||
import Chart from 'chart.js/auto';
|
||||
|
||||
@Component({
|
||||
selector: 'app-chart-login',
|
||||
standalone: true,
|
||||
imports: [],
|
||||
templateUrl: './login.component.html',
|
||||
styleUrl: './login.component.scss'
|
||||
})
|
||||
export class LoginChartComponent {
|
||||
chart: any = [];
|
||||
private http: HttpClient = inject(HttpClient);
|
||||
|
||||
constructor() {}
|
||||
|
||||
ngOnInit() {
|
||||
|
||||
|
||||
|
||||
this.getData();
|
||||
|
||||
}
|
||||
|
||||
private getData() {
|
||||
this.http.get<Login[]>('api/app/user/logins').subscribe(res => {
|
||||
console.log(res)
|
||||
this.createChart(res);
|
||||
})
|
||||
}
|
||||
|
||||
private createChart(data: Login[] ) {
|
||||
|
||||
|
||||
this.chart = new Chart('canvas', {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: data.map(d => new Date(d.date).toLocaleDateString('de-DE', {dateStyle: 'short'})),
|
||||
datasets: [
|
||||
{
|
||||
label: 'Logins',
|
||||
data: data.map(d => d.count.logins),
|
||||
borderWidth: 1,
|
||||
},{
|
||||
label: 'Applogins',
|
||||
data: data.map(d => d.count.systemLogins),
|
||||
borderWidth: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
},
|
||||
x: {
|
||||
stacked: true,
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
interface Login {
|
||||
date: string;
|
||||
count: { logins: number, systemLogins: number }
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<div>
|
||||
<canvas id="canvas">{{chart}}</canvas>
|
||||
</div>
|
||||
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { LoginComponent } from './login.component';
|
||||
|
||||
describe('LoginComponent', () => {
|
||||
let component: LoginComponent;
|
||||
let fixture: ComponentFixture<LoginComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [LoginComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(LoginComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -29,4 +29,6 @@
|
||||
<app-card [client]="client" (onDelete)="openDeleteDialog($event)" ></app-card>
|
||||
} -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<app-chart-login></app-chart-login>
|
||||
@@ -10,12 +10,12 @@ import { MatDialog, MatDialogModule } from '@angular/material/dialog';
|
||||
import { CreateClientComponent } from './components/create-client/create-client.component';
|
||||
import { CreateHotToastRef, HotToastService } from '@ngxpert/hot-toast';
|
||||
import {MatBottomSheet, MatBottomSheetModule, MatBottomSheetRef} from '@angular/material/bottom-sheet';
|
||||
import { ClientAdminsComponent } from './components/client-admins/client-admins.component';
|
||||
import { LoginChartComponent } from './components/charts/login/login.chart.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-dashboard',
|
||||
standalone: true,
|
||||
imports: [ClientCardComponent, MatButtonModule, MatIconModule, MatDialogModule, MatBottomSheetModule],
|
||||
imports: [ClientCardComponent, MatButtonModule, MatIconModule, MatDialogModule, MatBottomSheetModule, LoginChartComponent],
|
||||
templateUrl: './dashboard.component.html',
|
||||
styleUrl: './dashboard.component.scss'
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user