From 91bd85708cd86cf0a7ee17759436ff46316d7466 Mon Sep 17 00:00:00 2001 From: Flaminel Date: Thu, 22 May 2025 15:13:25 +0300 Subject: [PATCH] #32 --- code/UI/src/app/app.component.ts | 2 +- code/UI/src/app/app.config.ts | 3 +- code/UI/src/app/app.preset.ts | 53 ++++ .../dashboard-page.component.html | 203 +++++++++++++- .../dashboard-page.component.scss | 258 ++++++++++++++++-- .../dashboard-page.component.ts | 73 ++++- .../main-layout/main-layout.component.html | 6 +- .../logs-viewer/logs-viewer.component.html | 99 +++++-- .../logs-viewer/logs-viewer.component.scss | 222 +++++++++++++-- .../logs-viewer/logs-viewer.component.ts | 3 +- .../settings-page.component.html | 175 +++++++++--- .../settings-page.component.scss | 162 +++++++++-- .../settings-page/settings-page.component.ts | 159 ++++++++++- code/UI/src/styles.scss | 250 ++++++++++++++++- 14 files changed, 1514 insertions(+), 154 deletions(-) create mode 100644 code/UI/src/app/app.preset.ts diff --git a/code/UI/src/app/app.component.ts b/code/UI/src/app/app.component.ts index c4eb4fbd..8bbfa30e 100644 --- a/code/UI/src/app/app.component.ts +++ b/code/UI/src/app/app.component.ts @@ -10,5 +10,5 @@ import { MainLayoutComponent } from './layout/main-layout/main-layout.component' styleUrl: './app.component.scss' }) export class AppComponent { - title = 'CleanupErr'; + title = 'Cleanuparr'; } diff --git a/code/UI/src/app/app.config.ts b/code/UI/src/app/app.config.ts index eb27f1d4..720f6472 100644 --- a/code/UI/src/app/app.config.ts +++ b/code/UI/src/app/app.config.ts @@ -7,6 +7,7 @@ import Aura from '@primeng/themes/aura'; import { routes } from './app.routes'; import { provideServiceWorker } from '@angular/service-worker'; +import Noir from './app.preset'; export const appConfig: ApplicationConfig = { providers: [ @@ -16,7 +17,7 @@ export const appConfig: ApplicationConfig = { provideAnimationsAsync(), providePrimeNG({ theme: { - preset: Aura + preset: Noir } }), provideServiceWorker('ngsw-worker.js', { diff --git a/code/UI/src/app/app.preset.ts b/code/UI/src/app/app.preset.ts new file mode 100644 index 00000000..ec18ae34 --- /dev/null +++ b/code/UI/src/app/app.preset.ts @@ -0,0 +1,53 @@ +import { definePreset } from '@primeng/themes'; +import Aura from '@primeng/themes/aura'; + +const Noir = definePreset(Aura, { + semantic: { + // primary: { + // 50: '{violet.50}', + // 100: '{violet.100}', + // 200: '{violet.200}', + // 300: '{violet.300}', + // 400: '{violet.400}', + // 500: '{violet.500}', + // 600: '{violet.600}', + // 700: '{violet.700}', + // 800: '{violet.800}', + // 900: '{violet.900}', + // 950: '{violet.950}' + // }, + // colorScheme: { + // light: { + // primary: { + // color: '{violet.950}', + // inverseColor: '#ffffff', + // hoverColor: '{violet.900}', + // activeColor: '{violet.800}' + // }, + // highlight: { + // background: '{violet.950}', + // focusBackground: '{violet.700}', + // color: '#ffffff', + // focusColor: '#ffffff' + // } + // }, + // dark: { + // primary: { + // color: '{violet.50}', + // inverseColor: '{violet.950}', + // hoverColor: '{violet.100}', + // activeColor: '{violet.200}' + // }, + // highlight: { + // background: 'rgba(250, 250, 250, .16)', + // focusBackground: 'rgba(250, 250, 250, .24)', + // color: 'rgba(255,255,255,.87)', + // focusColor: 'rgba(255,255,255,.87)' + // } + // } + // } + } +}); + + +export default Noir; \ No newline at end of file diff --git a/code/UI/src/app/dashboard/dashboard-page/dashboard-page.component.html b/code/UI/src/app/dashboard/dashboard-page/dashboard-page.component.html index c64e0303..1f760c62 100644 --- a/code/UI/src/app/dashboard/dashboard-page/dashboard-page.component.html +++ b/code/UI/src/app/dashboard/dashboard-page/dashboard-page.component.html @@ -1,33 +1,190 @@ -
-

Dashboard

+
+
+

Dashboard

+ +
-
+ +
+
+
+
+ +
+
+
System Status
+
Operational
+
+
+
+ +
+
+
+ +
+
+
Services
+
All Running
+
+
+
+ +
+
+
+ +
+
+
Warnings
+
0 Warnings
+
+
+
+ +
+
+
+ +
+
+
Errors
+
0 Errors
+
+
+
+
+ + +
- + + +
+
+

Logs Summary

+ Recent logging activity +
+ +
+
-

Monitor your application logs and error statuses.

+
+
+ + Info Logs + 24 +
+ +
+ +
+
+ + Warning Logs + 10 +
+ +
+ +
+
+ + Error Logs + 3 +
+ +
+
- + + +
+
+

System Status

+ Current health status +
+ +
+
-

All systems operational

+
+ +
+
API Service
+
Running since 2 days
+
+ +
+ +
+ +
+
Log Hub
+
Connected
+
+ +
+ +
+ +
+
Database
+
Operational
+
+ +
+
- + + +
+
+

Updates & Info

+ System updates +
+ +
+
-

Your application is up to date.

+
+ +
+
System up to date
+
Latest version installed
+
+
+ +
+ +
+
Last scan
+
Today at 10:30 AM
+
+
+ +
+ +
+
Next scan scheduled
+
Tomorrow at 02:00 AM
+
+
+ @@ -35,4 +192,28 @@
+ + +
+
+ + + +
+
{{item.title}}
+
{{item.description}}
+
{{item.time}}
+
+
+ +
+ + + +
+
+
+
+
+
diff --git a/code/UI/src/app/dashboard/dashboard-page/dashboard-page.component.scss b/code/UI/src/app/dashboard/dashboard-page/dashboard-page.component.scss index 9881a64e..c6db448b 100644 --- a/code/UI/src/app/dashboard/dashboard-page/dashboard-page.component.scss +++ b/code/UI/src/app/dashboard/dashboard-page/dashboard-page.component.scss @@ -1,37 +1,259 @@ .dashboard-container { - padding: 1.5rem; - - h1 { - margin-top: 0; - margin-bottom: 1.5rem; - font-weight: 600; + padding: 0; + + .grid-container { + margin-bottom: 2rem; } + /* Overview Boxes */ + .overview-box { + border-radius: var(--border-radius); + padding: 1.5rem; + display: flex; + align-items: center; + color: white; + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); + transition: transform 0.3s, box-shadow 0.3s; + height: 100%; + + &:hover { + transform: translateY(-5px); + box-shadow: 0 6px 20px rgba(0, 0, 0, 0.15); + } + + .overview-icon { + width: 3rem; + height: 3rem; + border-radius: 50%; + background-color: rgba(255, 255, 255, 0.2); + display: flex; + align-items: center; + justify-content: center; + margin-right: 1rem; + + i { + font-size: 1.5rem; + } + } + + .overview-data { + flex: 1; + + .overview-value { + font-size: 1.1rem; + font-weight: 600; + margin-bottom: 0.25rem; + } + + .overview-label { + font-size: 0.9rem; + opacity: 0.9; + } + } + + &.bg-primary { + background-color: var(--primary-color); + background-image: linear-gradient(30deg, var(--primary-600), var(--primary-400)); + } + + &.bg-success { + background-color: var(--green-500); + background-image: linear-gradient(30deg, var(--green-600), var(--green-400)); + } + + &.bg-warning { + background-color: var(--yellow-500); + background-image: linear-gradient(30deg, var(--yellow-600), var(--yellow-400)); + color: var(--yellow-900); + } + + &.bg-danger { + background-color: var(--red-500); + background-image: linear-gradient(30deg, var(--red-600), var(--red-400)); + } + } + + /* Card styling */ + ::ng-deep { + .dashboard-card { + height: 100%; + transition: transform 0.3s, box-shadow 0.3s; + + &:hover { + transform: translateY(-3px); + box-shadow: 0 8px 15px rgba(0, 0, 0, 0.1); + } + + .p-card-header { + padding: 0; + } + + .card-title { + font-size: 1.25rem; + font-weight: 600; + margin-bottom: 0.25rem; + } + + .card-subtitle { + color: var(--text-color-secondary); + font-size: 0.875rem; + } + + .p-card-body { + height: 100%; + display: flex; + flex-direction: column; + padding: 0; + } + + .p-card-content { + flex-grow: 1; + padding: 1.5rem; + } + } + + /* Progress bar styling */ + .p-progressbar { + height: 8px; + background-color: var(--surface-200); + border-radius: 4px; + overflow: hidden; + + .p-progressbar-value { + background-color: var(--primary-color); + transition: width 0.5s ease; + } + + &.warning-progress .p-progressbar-value { + background-color: var(--yellow-500); + } + + &.danger-progress .p-progressbar-value { + background-color: var(--red-500); + } + } + + /* Timeline customizations */ + .activity-timeline { + .p-timeline-event-opposite { + flex: 0; + padding: 0 1rem; + } + + .p-timeline-event-content { + padding: 0 1rem 1.5rem 1rem; + } + + .activity-icon-container { + display: flex; + justify-content: center; + + .activity-icon { + width: 2.5rem; + height: 2.5rem; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + color: white; + + &.bg-primary { + background-color: var(--primary-color); + } + + &.bg-success { + background-color: var(--green-500); + } + + &.bg-info { + background-color: var(--blue-500); + } + + &.bg-warning { + background-color: var(--yellow-500); + } + + i { + font-size: 1rem; + } + } + } + + .activity-item { + background-color: var(--surface-card); + border-radius: var(--border-radius); + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04); + transition: transform 0.2s, box-shadow 0.2s; + + &:hover { + transform: translateX(3px); + box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); + } + } + } + } + + /* Status indicators */ + .status-indicator { + width: 10px; + height: 10px; + border-radius: 50%; + display: inline-block; + + &.active { + background-color: var(--green-500); + box-shadow: 0 0 0 3px rgba(80, 200, 120, 0.2); + } + + &.inactive { + background-color: var(--text-color-secondary); + } + + &.warning { + background-color: var(--yellow-500); + box-shadow: 0 0 0 3px rgba(255, 213, 79, 0.2); + } + + &.error { + background-color: var(--red-500); + box-shadow: 0 0 0 3px rgba(255, 86, 48, 0.2); + } + } + + /* Card content styling */ .card-content { - min-height: 100px; + min-height: 180px; display: flex; flex-direction: column; justify-content: space-between; } .card-footer { - margin-top: 1rem; + margin-top: 1.5rem; display: flex; justify-content: flex-end; + gap: 0.5rem; } - ::ng-deep .p-card { - height: 100%; - - .p-card-body { - height: 100%; - display: flex; - flex-direction: column; + /* Responsive adjustments */ + @media screen and (max-width: 768px) { + .overview-box { + margin-bottom: 1rem; } - .p-card-content { - flex-grow: 1; - padding-bottom: 0; + ::ng-deep .activity-timeline { + .p-timeline-event { + flex-direction: column !important; + + .p-timeline-event-opposite { + padding: 0; + margin-bottom: 0.5rem; + } + + .p-timeline-event-content { + padding: 0 0 1.5rem 2rem; + } + } } } } \ No newline at end of file diff --git a/code/UI/src/app/dashboard/dashboard-page/dashboard-page.component.ts b/code/UI/src/app/dashboard/dashboard-page/dashboard-page.component.ts index f97c59dc..9b9ce0ce 100644 --- a/code/UI/src/app/dashboard/dashboard-page/dashboard-page.component.ts +++ b/code/UI/src/app/dashboard/dashboard-page/dashboard-page.component.ts @@ -1,21 +1,86 @@ -import { Component } from '@angular/core'; -import { CommonModule } from '@angular/common'; +import { Component, OnInit } from '@angular/core'; +import { CommonModule, NgClass } from '@angular/common'; +import { RouterLink } from '@angular/router'; // PrimeNG Components import { CardModule } from 'primeng/card'; import { ButtonModule } from 'primeng/button'; +import { ProgressBarModule } from 'primeng/progressbar'; +import { TagModule } from 'primeng/tag'; +import { TimelineModule } from 'primeng/timeline'; + +// Models +interface ActivityItem { + title: string; + description: string; + time: string; + icon: string; + iconClass: string; +} @Component({ selector: 'app-dashboard-page', standalone: true, imports: [ CommonModule, + NgClass, + RouterLink, CardModule, - ButtonModule + ButtonModule, + ProgressBarModule, + TagModule, + TimelineModule ], templateUrl: './dashboard-page.component.html', styleUrl: './dashboard-page.component.scss' }) -export class DashboardPageComponent { +export class DashboardPageComponent implements OnInit { + // Sample activity items for the timeline + activityItems: ActivityItem[] = []; + ngOnInit() { + // Initialize dashboard data + this.initializeActivityData(); + } + + refreshDashboard() { + console.log('Refreshing dashboard data...'); + // Here you would normally fetch new data + // For now, we'll just reinitialize the demo data + this.initializeActivityData(); + } + + private initializeActivityData() { + // Sample activity data + this.activityItems = [ + { + title: 'System started', + description: 'Application services initialized successfully', + time: '10 minutes ago', + icon: 'pi pi-power-off', + iconClass: 'bg-primary' + }, + { + title: 'Database backup completed', + description: 'Automatic backup task executed successfully', + time: '2 hours ago', + icon: 'pi pi-database', + iconClass: 'bg-success' + }, + { + title: 'Configuration updated', + description: 'System configuration changes applied', + time: 'Yesterday, 14:23', + icon: 'pi pi-cog', + iconClass: 'bg-info' + }, + { + title: 'System update available', + description: 'New version 1.2.5 is available for installation', + time: '2 days ago', + icon: 'pi pi-download', + iconClass: 'bg-warning' + } + ]; + } } diff --git a/code/UI/src/app/layout/main-layout/main-layout.component.html b/code/UI/src/app/layout/main-layout/main-layout.component.html index 4c1ea825..9f26d825 100644 --- a/code/UI/src/app/layout/main-layout/main-layout.component.html +++ b/code/UI/src/app/layout/main-layout/main-layout.component.html @@ -9,7 +9,7 @@ aria-label="Toggle menu">
- CleanupErr + Cleanuparr
@@ -25,7 +25,7 @@