From 299cc565d7c5359d646cf6d6d82ae15e2129c6b7 Mon Sep 17 00:00:00 2001 From: Max Date: Thu, 30 May 2024 15:34:55 +0200 Subject: [PATCH] Added statistics - Added total file size statistic - Added total uploads statistic - Added total downloads statistic - Added icons to btns --- .../src/app/adminui/adminui.component.html | 147 +++++++++++++++++- frontend/src/app/adminui/adminui.component.ts | 79 +++++++++- frontend/src/app/app.routes.ts | 2 + frontend/src/app/login/login.component.html | 2 +- frontend/src/app/login/login.component.ts | 8 +- 5 files changed, 234 insertions(+), 4 deletions(-) diff --git a/frontend/src/app/adminui/adminui.component.html b/frontend/src/app/adminui/adminui.component.html index ac3e976..3429e3a 100644 --- a/frontend/src/app/adminui/adminui.component.html +++ b/frontend/src/app/adminui/adminui.component.html @@ -1 +1,146 @@ -

adminui works!

+
+

Admin Dashboard

+ + +
+
+
+
Total Files Uploaded
+
{{ fileUploads.length + expiredFileUploads.length }}
+
Since launch
+
+
+ +
+
+
Total File Size on Disk
+
{{ totalFileSizeOnDisk | formatFileSizePipe }}
+
Across all files
+
+
+ +
+
+
Operational For
+
2 Years
+
Since launch
+
+
+ +
+
+
Total Downloads
+
{{ totalFileDownloads }}
+
All time
+
+
+ +
+
+
Last Admin Login
+
2 days ago
+
Most recent login
+
+
+
+ + +
+ + + + + +
+ +
+ + +

Active file uploads

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Entity IDFile IDFile NameFile SizeSingle DownloadDisabledUpload DateUploaded By IPDownload CountPassword Protected
{{ file.id }}{{ file.fileId }}{{ file.fileName }}{{ file.fileSize | formatFileSizePipe }}{{ file.singleDownload ? 'true' : 'false' }}{{ file.disabled ? 'true' : 'false' }}{{ file.uploadDate | date: 'medium' }}{{ file.uploadedByIpAddress }}{{ file.downloadCount }}{{ file.passwordProtected ? 'true' : 'false' }}
+
+ +

Expired file uploads

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Entity IDFile IDFile NameFile SizeSingle DownloadDisabledUpload DateUploaded By IPDownload CountPassword Protected
{{ file.id }}{{ file.fileId }}{{ file.fileName }}{{ file.fileSize | number }}{{ file.singleDownload ? 'true' : 'false' }}{{ file.disabled ? 'true' : 'false' }}{{ file.uploadDate | date: 'medium' }}{{ file.uploadedByIpAddress }}{{ file.downloadCount }}{{ file.passwordProtected ? 'true' : 'false' }}
+
+
diff --git a/frontend/src/app/adminui/adminui.component.ts b/frontend/src/app/adminui/adminui.component.ts index 948bec9..fd2b4b4 100644 --- a/frontend/src/app/adminui/adminui.component.ts +++ b/frontend/src/app/adminui/adminui.component.ts @@ -1,12 +1,89 @@ import { Component } from '@angular/core'; +import {DatePipe, DecimalPipe, NgForOf} from "@angular/common"; +import axios from "axios"; +import {firstValueFrom} from "rxjs"; +import {DevelopmentStore} from "../../store/DevelopmentStore"; +import {AuthStore} from "../../store/authStore"; +import {Router} from "@angular/router"; +import {FormatFileSizePipePipe} from "../format-file-size-pipe.pipe"; @Component({ selector: 'app-adminui', standalone: true, - imports: [], + imports: [ + DatePipe, + DecimalPipe, + NgForOf, + FormatFileSizePipePipe + ], templateUrl: './adminui.component.html', styleUrl: './adminui.component.scss' }) export class AdminuiComponent { + fileUploads: any[] = []; + expiredFileUploads: any[] = []; + totalFileSizeOnDisk: number = 0; + totalFileDownloads = 0; + + constructor(private developmentStore: DevelopmentStore, private authStore: AuthStore, private router: Router) { + this.verifyToken(); + } + + async verifyToken() { + if(await firstValueFrom(this.authStore.token$) === "") { + console.log("No token present, redirecting to login..."); + await this.router.navigate(['/login']); + return; + } + await this.fetchFileUploads(); + await this.fetchExpiredFileUploads(); + await this.calculateStatistics(); + } + + async calculateStatistics() { + console.log("Calculating statistics..."); + console.log(this.fileUploads) + for(let fileUpload of this.fileUploads) { + this.totalFileSizeOnDisk += fileUpload.fileSize; + } + + for(let fileUpload of this.expiredFileUploads) { + this.totalFileDownloads += fileUpload.downloadCount; + } + for(let fileUpload of this.fileUploads) { + this.totalFileDownloads += fileUpload.downloadCount; + } + } + + async fetchFileUploads() { + try { + const response = await axios({ + method: 'get', + url: this.developmentStore.getBaseUrl() + 'api/v1/secure/upload-history', + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer ' + await firstValueFrom(this.authStore.token$) + } + }); + this.fileUploads = response.data; + } catch (error) { + console.error(error); + } + } + async fetchExpiredFileUploads() { + try { + const response = await axios({ + method: 'get', + url: this.developmentStore.getBaseUrl() + 'api/v1/secure/expired-upload-history', + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer ' + await firstValueFrom(this.authStore.token$) + } + }); + this.expiredFileUploads = response.data; + } catch (error) { + console.error(error); + } + } } diff --git a/frontend/src/app/app.routes.ts b/frontend/src/app/app.routes.ts index 51d840a..4f6ea4f 100644 --- a/frontend/src/app/app.routes.ts +++ b/frontend/src/app/app.routes.ts @@ -5,6 +5,7 @@ import {DownloadComponent} from "./download/download.component"; import {CreditsComponent} from "./credits/credits.component"; import {LicensesComponent} from "./credits/licenses/licenses.component"; import {LoginComponent} from "./login/login.component"; +import {AdminuiComponent} from "./adminui/adminui.component"; export const routes: Routes = [ { path: '', redirectTo: 'home', pathMatch: 'full' }, @@ -14,6 +15,7 @@ export const routes: Routes = [ { path: 'credits', component: CreditsComponent }, { path: 'licenses', component: LicensesComponent }, { path: 'login', component: LoginComponent }, + { path: 'secure/administration', component: AdminuiComponent}, // { path: 'download/:id', component: DownloadComponent } { path: '**', redirectTo: 'home' } ]; diff --git a/frontend/src/app/login/login.component.html b/frontend/src/app/login/login.component.html index 3c45505..2c2cb22 100644 --- a/frontend/src/app/login/login.component.html +++ b/frontend/src/app/login/login.component.html @@ -8,7 +8,7 @@ + [ngClass]="{'input-error': loginFailed}" autofocus >