diff --git a/apps/frontend/src/app/app.component.html b/apps/frontend/src/app/app.component.html index ad71637e..546ee820 100644 --- a/apps/frontend/src/app/app.component.html +++ b/apps/frontend/src/app/app.component.html @@ -18,7 +18,7 @@ routerLinkActive="active" routerLink="email-receiver" class="nav-text" - >Email ReceiverEmail Receiver @@ -41,10 +41,19 @@ clrVerticalNavLink clrAriaCurrentLink routerLink="/" + [routerLinkActiveOptions]="{ exact: true }" routerLinkActive="active" class="nav-link" - >Overview + >Overview + Backup Statistics + diff --git a/apps/frontend/src/app/app.component.spec.ts b/apps/frontend/src/app/app.component.spec.ts index d35795ac..821c1c12 100644 --- a/apps/frontend/src/app/app.component.spec.ts +++ b/apps/frontend/src/app/app.component.spec.ts @@ -52,7 +52,7 @@ describe('AppComponent', () => { it('should have navigation items', () => { const navItems = fixture.debugElement.queryAll(By.css('.nav-text')); - const expectedNavItems = ['Dashboard', 'Overview', 'Upload', 'Find Data']; + const expectedNavItems = ['Dashboard', 'Overview', 'Backup Statistics', 'Upload', 'Find Data']; // Use a Set to get unique nav item texts const uniqueNavItems = [ @@ -67,7 +67,7 @@ describe('AppComponent', () => { it('should have router links configured', () => { const routerLinks = fixture.debugElement.queryAll(By.css('[routerLink]')); - const expectedRoutes = ['/', '/', '/upload', '/findData']; + const expectedRoutes = ['/', '/', '/backup-statistics', '/upload', '/findData']; routerLinks.forEach((link, index) => { expect(link.nativeElement.getAttribute('routerLink')).toBe( diff --git a/apps/frontend/src/app/app.module.ts b/apps/frontend/src/app/app.module.ts index effa95d5..54fa322a 100644 --- a/apps/frontend/src/app/app.module.ts +++ b/apps/frontend/src/app/app.module.ts @@ -17,6 +17,7 @@ import { envelopeIcon, errorStandardIcon, filterIcon, + helpIcon, homeIcon, lockIcon, plusIcon, @@ -30,23 +31,24 @@ import { import { NgxEchartsModule } from 'ngx-echarts'; import { TestUploadComponent } from './test-upload/component/test-upload/test-upload.component'; import { FindTestDataComponent } from './test-upload/component/find-test-data/find-test-data.component'; -import { BackupsComponent } from './backups-overview/component/backups.component'; +import { OverviewPageComponent } from './backups-overview-page/component/overview-page.component'; import { BASE_URL } from './shared/types/configuration'; -import { AlertComponent } from './alert/component/alert.component'; +import { AlertComponent } from './backups-overview-page/component/alert-panel/component/alert.component'; import { NotificationSettingsComponent } from './management/components/settings/notification-settings/notification-settings.component'; import { EmailReceiverSettingsComponent } from './management/components/settings/email-receiver-settings/email-receiver-settings.component'; import { ConfirmDialogComponent } from './shared/components/confirm-dialog/component/confirm-dialog/confirm-dialog.component'; -import { DataStoresComponent } from './data-stores/component/data-stores.component'; -import { InformationPanelComponent } from './backups-overview/component/information-panel/information-panel.component'; -import { BackupTableComponent } from './backups-overview/component/backup-table/backup-table.component'; -import { SidePanelComponent } from './backups-overview/component/side-panel/side-panel.component'; +import { DataStoresComponent } from './backups-overview-page/component/data-stores-panel/data-stores.component'; +import { InformationPanelComponent } from './backups-overview-page/component/information-panel/information-panel.component'; +import { BackupTableComponent } from './backup-statistics-page/component/backup-table/backup-table.component'; +import { SidePanelComponent } from './shared/components/filter-side-panel/side-panel.component'; +import { BackupStatisticsPageComponent } from './backup-statistics-page/component/backup-statistics-page.component'; @NgModule({ declarations: [ AppComponent, TestUploadComponent, FindTestDataComponent, - BackupsComponent, + OverviewPageComponent, AlertComponent, NotificationSettingsComponent, EmailReceiverSettingsComponent, @@ -55,6 +57,7 @@ import { SidePanelComponent } from './backups-overview/component/side-panel/side InformationPanelComponent, BackupTableComponent, SidePanelComponent, + BackupStatisticsPageComponent ], imports: [ BrowserModule, @@ -88,7 +91,8 @@ export class AppModule { envelopeIcon, plusIcon, lockIcon, - trashIcon + trashIcon, + helpIcon ); } } diff --git a/apps/frontend/src/app/app.routes.ts b/apps/frontend/src/app/app.routes.ts index d5331da8..e22f5c84 100644 --- a/apps/frontend/src/app/app.routes.ts +++ b/apps/frontend/src/app/app.routes.ts @@ -1,13 +1,15 @@ import { Route } from '@angular/router'; import { TestUploadComponent } from './test-upload/component/test-upload/test-upload.component'; import { FindTestDataComponent } from './test-upload/component/find-test-data/find-test-data.component'; -import { BackupsComponent } from './backups-overview/component/backups.component'; +import { OverviewPageComponent } from './backups-overview-page/component/overview-page.component'; import { EmailReceiverSettingsComponent } from './management/components/settings/email-receiver-settings/email-receiver-settings.component'; +import { BackupStatisticsPageComponent } from './backup-statistics-page/component/backup-statistics-page.component'; export const appRoutes: Route[] = [ { path: 'upload', component: TestUploadComponent }, { path: 'findData', component: FindTestDataComponent }, { path: 'email-receiver', component: EmailReceiverSettingsComponent}, - { path: '', component: BackupsComponent }, + { path: 'backup-statistics', component: BackupStatisticsPageComponent }, + { path: '', component: OverviewPageComponent }, ]; diff --git a/apps/frontend/src/app/backup-statistics-page/component/backup-statistics-page.component.css b/apps/frontend/src/app/backup-statistics-page/component/backup-statistics-page.component.css new file mode 100644 index 00000000..cee607e4 --- /dev/null +++ b/apps/frontend/src/app/backup-statistics-page/component/backup-statistics-page.component.css @@ -0,0 +1,33 @@ +.header { + background-color: white; + justify-content: space-around; + position: relative; +} + +.card-block { + padding: 20px; +} + +.clr-form-control { + margin-top: 0; +} + +.card-header { + display: flex; + justify-content: space-between; + align-items: center; +} + +.card-header-title { + margin: 0; + font-weight: 500; +} + +.card-header-actions { + display: flex; + align-items: center; +} + +:host ::ng-deep .card-header { + border-bottom: none !important; +} diff --git a/apps/frontend/src/app/backups-overview/component/backups.component.html b/apps/frontend/src/app/backup-statistics-page/component/backup-statistics-page.component.html similarity index 80% rename from apps/frontend/src/app/backups-overview/component/backups.component.html rename to apps/frontend/src/app/backup-statistics-page/component/backup-statistics-page.component.html index f73855ff..5f691f0f 100644 --- a/apps/frontend/src/app/backups-overview/component/backups.component.html +++ b/apps/frontend/src/app/backup-statistics-page/component/backup-statistics-page.component.html @@ -1,11 +1,7 @@ -

Backups Overview

-
- - -
+

Backups Statistics

- +
@@ -27,7 +23,7 @@

Backups Overview

@@ -53,13 +49,10 @@

Backups Overview

-
+
-
- -
\ No newline at end of file diff --git a/apps/frontend/src/app/backups-overview/component/backups.component.spec.ts b/apps/frontend/src/app/backup-statistics-page/component/backup-statistics-page.component.spec.ts similarity index 67% rename from apps/frontend/src/app/backups-overview/component/backups.component.spec.ts rename to apps/frontend/src/app/backup-statistics-page/component/backup-statistics-page.component.spec.ts index b0383718..61a67455 100644 --- a/apps/frontend/src/app/backups-overview/component/backups.component.spec.ts +++ b/apps/frontend/src/app/backup-statistics-page/component/backup-statistics-page.component.spec.ts @@ -1,16 +1,15 @@ import { beforeEach, describe, expect, it } from 'vitest'; import { TestBed } from '@angular/core/testing'; +import { BackupStatisticsPageComponent } from './backup-statistics-page.component'; -import { BackupsComponent } from './backups.component'; - -describe('BackupsComponent', () => { - let component: BackupsComponent; +describe('BackupStatisticsPageComponent', () => { + let component: BackupStatisticsPageComponent; beforeEach(() => { TestBed.configureTestingModule({ - providers: [BackupsComponent], + providers: [BackupStatisticsPageComponent], }); - component = TestBed.inject(BackupsComponent); + component = TestBed.inject(BackupStatisticsPageComponent); }); it('should create the component', () => { diff --git a/apps/frontend/src/app/backup-statistics-page/component/backup-statistics-page.component.ts b/apps/frontend/src/app/backup-statistics-page/component/backup-statistics-page.component.ts new file mode 100644 index 00000000..939d705f --- /dev/null +++ b/apps/frontend/src/app/backup-statistics-page/component/backup-statistics-page.component.ts @@ -0,0 +1,39 @@ +import { Component, ViewChild, AfterViewInit } from '@angular/core'; +import { ChartInformation } from '../../shared/types/chartInformation'; +import { ChartType } from '../../shared/enums/chartType'; +import { SidePanelComponent } from '../../shared/components/filter-side-panel/side-panel.component'; +import { BehaviorSubject } from 'rxjs'; +import { BackupTask } from '../../shared/types/backup.task'; + +@Component({ + selector: 'app-backup-statistics-page', + templateUrl: './backup-statistics-page.component.html', + styleUrl: './backup-statistics-page.component.css', +}) +export class BackupStatisticsPageComponent implements AfterViewInit { + @ViewChild(SidePanelComponent) sidePanelComponent!: SidePanelComponent; + backupTaskSubject$: BehaviorSubject | undefined; + protected filterPanel = false; + + readonly charts: ChartInformation[] = [ + { + id: 'backupStatisticsPageSizePieChart', + type: ChartType.SIZEPIECHART, + }, + { + id: 'backupStatisticsPageSizeColumnChart', + type: ChartType.SIZECOLUMNCHART, + }, + ]; + + ngAfterViewInit(): void { + this.backupTaskSubject$ = this.sidePanelComponent.backupTaskSubject$; + } + + /** + * Change the state of the filter panel to open or close it + */ + protected changeFilterPanelState(): void { + this.filterPanel = !this.filterPanel; + } +} diff --git a/apps/frontend/src/app/backups-overview/component/backup-table/backup-table.component.css b/apps/frontend/src/app/backup-statistics-page/component/backup-table/backup-table.component.css similarity index 100% rename from apps/frontend/src/app/backups-overview/component/backup-table/backup-table.component.css rename to apps/frontend/src/app/backup-statistics-page/component/backup-table/backup-table.component.css diff --git a/apps/frontend/src/app/backups-overview/component/backup-table/backup-table.component.html b/apps/frontend/src/app/backup-statistics-page/component/backup-table/backup-table.component.html similarity index 100% rename from apps/frontend/src/app/backups-overview/component/backup-table/backup-table.component.html rename to apps/frontend/src/app/backup-statistics-page/component/backup-table/backup-table.component.html diff --git a/apps/frontend/src/app/backups-overview/component/backup-table/backup-table.component.spec.ts b/apps/frontend/src/app/backup-statistics-page/component/backup-table/backup-table.component.spec.ts similarity index 97% rename from apps/frontend/src/app/backups-overview/component/backup-table/backup-table.component.spec.ts rename to apps/frontend/src/app/backup-statistics-page/component/backup-table/backup-table.component.spec.ts index 005658ee..729fd86d 100644 --- a/apps/frontend/src/app/backups-overview/component/backup-table/backup-table.component.spec.ts +++ b/apps/frontend/src/app/backup-statistics-page/component/backup-table/backup-table.component.spec.ts @@ -5,9 +5,9 @@ import { BackupTableComponent } from './backup-table.component'; import { Backup } from '../../../shared/types/backup'; import { APIResponse } from '../../../shared/types/api-response'; import { BackupType } from '../../../shared/enums/backup.types'; -import { BackupService } from '../../service/backup-service/backup-service.service'; +import { BackupService } from '../../../shared/services/backup-service/backup-service.service'; import { ClrDatagridStateInterface } from '@clr/angular'; -import { CustomFilter } from '../backupfilter'; +import { CustomFilter } from '../../../backups-overview-page/component/backupfilter'; describe('BackupTableComponent', () => { let component: BackupTableComponent; diff --git a/apps/frontend/src/app/backups-overview/component/backup-table/backup-table.component.ts b/apps/frontend/src/app/backup-statistics-page/component/backup-table/backup-table.component.ts similarity index 96% rename from apps/frontend/src/app/backups-overview/component/backup-table/backup-table.component.ts rename to apps/frontend/src/app/backup-statistics-page/component/backup-table/backup-table.component.ts index 692f53f9..f8904af2 100644 --- a/apps/frontend/src/app/backups-overview/component/backup-table/backup-table.component.ts +++ b/apps/frontend/src/app/backup-statistics-page/component/backup-table/backup-table.component.ts @@ -1,5 +1,5 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; -import { CustomFilter } from '../backupfilter'; +import { CustomFilter } from '../../../backups-overview-page/component/backupfilter'; import { BehaviorSubject, combineLatest, @@ -12,7 +12,7 @@ import { } from 'rxjs'; import { APIResponse } from '../../../shared/types/api-response'; import { Backup } from '../../../shared/types/backup'; -import { BackupService } from '../../service/backup-service/backup-service.service'; +import { BackupService } from '../../../shared/services/backup-service/backup-service.service'; import { BackupFilterParams } from '../../../shared/types/backup-filter-type'; import { BackupType } from '../../../shared/enums/backup.types'; import { ClrDatagridSortOrder, ClrDatagridStateInterface } from '@clr/angular'; diff --git a/apps/frontend/src/app/alert/component/alert.component.css b/apps/frontend/src/app/backups-overview-page/component/alert-panel/component/alert.component.css similarity index 100% rename from apps/frontend/src/app/alert/component/alert.component.css rename to apps/frontend/src/app/backups-overview-page/component/alert-panel/component/alert.component.css diff --git a/apps/frontend/src/app/alert/component/alert.component.html b/apps/frontend/src/app/backups-overview-page/component/alert-panel/component/alert.component.html similarity index 100% rename from apps/frontend/src/app/alert/component/alert.component.html rename to apps/frontend/src/app/backups-overview-page/component/alert-panel/component/alert.component.html diff --git a/apps/frontend/src/app/alert/component/alert.component.spec.ts b/apps/frontend/src/app/backups-overview-page/component/alert-panel/component/alert.component.spec.ts similarity index 98% rename from apps/frontend/src/app/alert/component/alert.component.spec.ts rename to apps/frontend/src/app/backups-overview-page/component/alert-panel/component/alert.component.spec.ts index 67f1123e..6f01b3fc 100644 --- a/apps/frontend/src/app/alert/component/alert.component.spec.ts +++ b/apps/frontend/src/app/backups-overview-page/component/alert-panel/component/alert.component.spec.ts @@ -1,9 +1,9 @@ import { beforeEach, describe, expect, it, Mock, vi } from 'vitest'; import { AlertComponent } from './alert.component'; import { of } from 'rxjs'; -import { Alert, SizeAlert } from '../../shared/types/alert'; +import { Alert, SizeAlert } from '../../../../shared/types/alert'; import { randomUUID } from 'crypto'; -import { SeverityType } from '../../shared/enums/severityType'; +import { SeverityType } from '../../../../shared/enums/severityType'; describe('AlertComponent', () => { let component: AlertComponent; diff --git a/apps/frontend/src/app/alert/component/alert.component.ts b/apps/frontend/src/app/backups-overview-page/component/alert-panel/component/alert.component.ts similarity index 94% rename from apps/frontend/src/app/alert/component/alert.component.ts rename to apps/frontend/src/app/backups-overview-page/component/alert-panel/component/alert.component.ts index 0865b8c4..1cadd9ff 100644 --- a/apps/frontend/src/app/alert/component/alert.component.ts +++ b/apps/frontend/src/app/backups-overview-page/component/alert-panel/component/alert.component.ts @@ -1,14 +1,14 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; -import { AlertServiceService } from '../service/alert-service.service'; +import { AlertServiceService } from '../../../../shared/services/alert-service/alert-service.service'; import { Alert, CreationDateAlert, SizeAlert, StorageFillAlert, -} from '../../shared/types/alert'; +} from '../../../../shared/types/alert'; import { DatePipe } from '@angular/common'; import { Subject, takeUntil, tap } from 'rxjs'; -import { SeverityType } from '../../shared/enums/severityType'; +import { SeverityType } from '../../../../shared/enums/severityType'; @Component({ selector: 'app-alert', @@ -21,9 +21,9 @@ export class AlertComponent implements OnInit, OnDestroy { readonly DAYS = 7; alerts: Alert[] = []; - criticalAlertsCount: number = 0; - warningAlertsCount: number = 0; - infoAlertsCount: number = 0; + criticalAlertsCount = 0; + warningAlertsCount = 0; + infoAlertsCount = 0; status: 'OK' | 'Warning' | 'Critical' = 'OK'; diff --git a/apps/frontend/src/app/backups-overview/component/backupfilter.ts b/apps/frontend/src/app/backups-overview-page/component/backupfilter.ts similarity index 100% rename from apps/frontend/src/app/backups-overview/component/backupfilter.ts rename to apps/frontend/src/app/backups-overview-page/component/backupfilter.ts diff --git a/apps/frontend/src/app/data-stores/component/data-stores.component.css b/apps/frontend/src/app/backups-overview-page/component/data-stores-panel/data-stores.component.css similarity index 94% rename from apps/frontend/src/app/data-stores/component/data-stores.component.css rename to apps/frontend/src/app/backups-overview-page/component/data-stores-panel/data-stores.component.css index abc9c303..c412a7d8 100644 --- a/apps/frontend/src/app/data-stores/component/data-stores.component.css +++ b/apps/frontend/src/app/backups-overview-page/component/data-stores-panel/data-stores.component.css @@ -11,7 +11,7 @@ .progress-bar-container { position: relative; - width: 70%; + width: 100%; display: inline-block; vertical-align: middle; --clr-progress-bg-color: #C6DCF2; @@ -34,7 +34,7 @@ } .card-header { - background-color: #f5f5f5; + background-color: #f3f8fb; padding: 10px; border-bottom: 1px solid #dcdcdc; display: flex; @@ -51,7 +51,7 @@ } .card-footer { - background-color: #f5f5f5; + background-color: #f3f8fb; border-top: 1px solid #dcdcdc; text-align: right; border-bottom-left-radius: 10px; diff --git a/apps/frontend/src/app/data-stores/component/data-stores.component.html b/apps/frontend/src/app/backups-overview-page/component/data-stores-panel/data-stores.component.html similarity index 100% rename from apps/frontend/src/app/data-stores/component/data-stores.component.html rename to apps/frontend/src/app/backups-overview-page/component/data-stores-panel/data-stores.component.html diff --git a/apps/frontend/src/app/data-stores/component/data-stores.component.spec.ts b/apps/frontend/src/app/backups-overview-page/component/data-stores-panel/data-stores.component.spec.ts similarity index 97% rename from apps/frontend/src/app/data-stores/component/data-stores.component.spec.ts rename to apps/frontend/src/app/backups-overview-page/component/data-stores-panel/data-stores.component.spec.ts index 748d8f88..d7722c25 100644 --- a/apps/frontend/src/app/data-stores/component/data-stores.component.spec.ts +++ b/apps/frontend/src/app/backups-overview-page/component/data-stores-panel/data-stores.component.spec.ts @@ -2,7 +2,7 @@ import { beforeEach, describe, expect, it, Mock, vi } from 'vitest'; import { of } from 'rxjs'; import { randomUUID } from 'crypto'; import { DataStoresComponent } from './data-stores.component'; -import { DataStore } from '../../shared/types/data-store'; +import { DataStore } from '../../../shared/types/data-store'; const dataStores: DataStore[] = [ { diff --git a/apps/frontend/src/app/data-stores/component/data-stores.component.ts b/apps/frontend/src/app/backups-overview-page/component/data-stores-panel/data-stores.component.ts similarity index 88% rename from apps/frontend/src/app/data-stores/component/data-stores.component.ts rename to apps/frontend/src/app/backups-overview-page/component/data-stores-panel/data-stores.component.ts index bc929003..20be1367 100644 --- a/apps/frontend/src/app/data-stores/component/data-stores.component.ts +++ b/apps/frontend/src/app/backups-overview-page/component/data-stores-panel/data-stores.component.ts @@ -1,7 +1,7 @@ import { Component, OnDestroy } from '@angular/core'; -import { DataStoresService } from '../service/data-stores-service.service'; +import { DataStoresService } from '../../../shared/services/data-stores-service/data-stores-service.service'; import { map, Observable, shareReplay, Subject, takeUntil } from 'rxjs'; -import { DataStore } from '../../shared/types/data-store'; +import { DataStore } from '../../../shared/types/data-store'; @Component({ selector: 'app-data-stores', diff --git a/apps/frontend/src/app/backups-overview/component/information-panel/information-panel.component.css b/apps/frontend/src/app/backups-overview-page/component/information-panel/information-panel.component.css similarity index 100% rename from apps/frontend/src/app/backups-overview/component/information-panel/information-panel.component.css rename to apps/frontend/src/app/backups-overview-page/component/information-panel/information-panel.component.css diff --git a/apps/frontend/src/app/backups-overview-page/component/information-panel/information-panel.component.html b/apps/frontend/src/app/backups-overview-page/component/information-panel/information-panel.component.html new file mode 100644 index 00000000..12607384 --- /dev/null +++ b/apps/frontend/src/app/backups-overview-page/component/information-panel/information-panel.component.html @@ -0,0 +1,31 @@ +
+
+
+ +

+ Welcome to the Metadata Analyzer! +

+ The Metadata Analyzer is a powerful tool designed to provide in-depth insights into your backup data by + analyzing metadata generated during backup creation. With a focus on efficiency and clarity, the Metadata + Analyzer processes and evaluates key information, to provide valuable insights about apects including: +
+
+
    +
  • Backup Creation Date: Track when backups were generated to ensure timely data management.
  • +
  • Backup Size: Gain visibility into storage consumption and optimize capacity planning.
  • +
  • Backup Tasks: Monitor and assess the specific tasks performed during the backup process.
  • +
+
+ Alert Functionality for Proactive Management + Stay informed with our integrated alert system. Subscribed users can receive real-time notifications via email + about critical events or thresholds, ensuring they are always ahead of potential issues. +
+ Whether you need detailed reports, enhanced monitoring, or proactive alerts, the Metadata Analyzer equips you + with the tools needed to monitore your backups effectively and with confidence. +
+ It is important to note, that this tool does not know or process any content of backups analyzed. All + information is only gathered based on the metadata of the backups made. +
+
+
+
\ No newline at end of file diff --git a/apps/frontend/src/app/backups-overview/component/information-panel/information-panel.component.ts b/apps/frontend/src/app/backups-overview-page/component/information-panel/information-panel.component.ts similarity index 100% rename from apps/frontend/src/app/backups-overview/component/information-panel/information-panel.component.ts rename to apps/frontend/src/app/backups-overview-page/component/information-panel/information-panel.component.ts diff --git a/apps/frontend/src/app/backups-overview-page/component/overview-page.component.css b/apps/frontend/src/app/backups-overview-page/component/overview-page.component.css new file mode 100644 index 00000000..ba07aa89 --- /dev/null +++ b/apps/frontend/src/app/backups-overview-page/component/overview-page.component.css @@ -0,0 +1,92 @@ +.header { + background-color: white; + justify-content: space-around; + position: relative; +} + +.info-panel { + border: 1px solid #0D233A; + display: flex; + align-items: center; + padding: 2px; + padding-left: 8px; + padding-right: 8px; + border-radius: 8px; + cursor: pointer; + justify-content: space-between; +} + +.info-badge { + color: #0D233A; + width: 30px; + height: 30px; + margin-left: 6px; +} + +.card { + border: 1px solid #dcdcdc; + border-radius: 10px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + margin-bottom: 20px; + background-color: #ffffff; +} + +.card-header { + background-color: #f3f8fb; + padding: 10px; + border-bottom: 1px solid #dcdcdc; + display: flex; + justify-content: space-between; + align-items: center; + border-top-left-radius: 10px; + border-top-right-radius: 10px; +} + +.card-header-title { + margin: 0; + font-weight: 600; + font-size: 1em; + color: #333333; +} + +.card-header-actions { + display: flex; + align-items: center; +} + +.card-block { + padding: 20px; + background-color: #ffffff; +} + +.card-footer { + background-color: #f3f8fb; + border-top: 1px solid #dcdcdc; + text-align: right; + padding: 10px; + border-bottom-left-radius: 10px; + border-bottom-right-radius: 10px; +} + +.btn-link { + color: #007bff; + text-decoration: none; + background-color: transparent; + border: none; + padding: 0; + font-size: 1em; + cursor: pointer; +} + +.btn-link:hover { + text-decoration: underline; +} + +.badge-info { + background-color: #0D233A; + color: #ffffff; + width: 20px; + height: 20px; + border-radius: 20px; + font-size: 14px; +} diff --git a/apps/frontend/src/app/backups-overview-page/component/overview-page.component.html b/apps/frontend/src/app/backups-overview-page/component/overview-page.component.html new file mode 100644 index 00000000..f13b7213 --- /dev/null +++ b/apps/frontend/src/app/backups-overview-page/component/overview-page.component.html @@ -0,0 +1,45 @@ +

Overview

+
+
+ About this page + +
+ + +
+
+ + +
+ + +
+
+
+
+
Recent Backup Timeline:
+
+ +
+
+
+
+
+
+
+
+
+ + \ No newline at end of file diff --git a/apps/frontend/src/app/backups-overview-page/component/overview-page.component.spec.ts b/apps/frontend/src/app/backups-overview-page/component/overview-page.component.spec.ts new file mode 100644 index 00000000..9d31e242 --- /dev/null +++ b/apps/frontend/src/app/backups-overview-page/component/overview-page.component.spec.ts @@ -0,0 +1,43 @@ +import { beforeEach, describe, expect, it } from 'vitest'; +import { TestBed } from '@angular/core/testing'; + +import { OverviewPageComponent } from './overview-page.component'; + +describe('OverviewPageComponent', () => { + let component: OverviewPageComponent; + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [OverviewPageComponent], + }); + + component = TestBed.inject(OverviewPageComponent); + }); + + it('should create the component', () => { + expect(component).toBeTruthy(); + }); + + describe('Filter Panel', () => { + it('should toggle filter panel state', () => { + expect(component['filterPanel']).toBe(false); + + component['changeFilterPanelState'](); + expect(component['filterPanel']).toBe(true); + + component['changeFilterPanelState'](); + expect(component['filterPanel']).toBe(false); + }); + }); + + describe('Information Panel', () => { + it('should toggle information panel state', () => { + expect(component['isInfoPanelOpen']).toBe(false); + + component['toggleInfoPanel'](); + expect(component['isInfoPanelOpen']).toBe(true); + + component['toggleInfoPanel'](); + expect(component['isInfoPanelOpen']).toBe(false); + }); + }); +}); diff --git a/apps/frontend/src/app/backups-overview/component/backups.component.ts b/apps/frontend/src/app/backups-overview-page/component/overview-page.component.ts similarity index 68% rename from apps/frontend/src/app/backups-overview/component/backups.component.ts rename to apps/frontend/src/app/backups-overview-page/component/overview-page.component.ts index 15ac9b22..6b13a5b0 100644 --- a/apps/frontend/src/app/backups-overview/component/backups.component.ts +++ b/apps/frontend/src/app/backups-overview-page/component/overview-page.component.ts @@ -1,30 +1,27 @@ import { AfterViewInit, Component, ViewChild } from '@angular/core'; -import { SidePanelComponent } from './side-panel/side-panel.component'; +import { SidePanelComponent } from '../../shared/components/filter-side-panel/side-panel.component'; import { BehaviorSubject } from 'rxjs'; import { BackupTask } from '../../shared/types/backup.task'; import { ChartType } from '../../shared/enums/chartType'; import { ChartInformation } from '../../shared/types/chartInformation'; @Component({ - selector: 'app-backups', - templateUrl: './backups.component.html', - styleUrl: './backups.component.css', + selector: 'app-overview-page', + templateUrl: './overview-page.component.html', + styleUrl: './overview-page.component.css', }) -export class BackupsComponent implements AfterViewInit { +export class OverviewPageComponent implements AfterViewInit { @ViewChild(SidePanelComponent) sidePanelComponent!: SidePanelComponent; backupTaskSubject$: BehaviorSubject | undefined; readonly charts: ChartInformation[] = [ - { - id: 'overviewSizePieChart', - type: ChartType.SIZEPIECHART, - }, { id: 'overviewSizeColumnChart', type: ChartType.SIZECOLUMNCHART, }, ]; + protected isInfoPanelOpen = false; protected filterPanel = false; ngAfterViewInit(): void { @@ -37,4 +34,8 @@ export class BackupsComponent implements AfterViewInit { protected changeFilterPanelState(): void { this.filterPanel = !this.filterPanel; } + + protected toggleInfoPanel() { + this.isInfoPanelOpen = !this.isInfoPanelOpen; + } } diff --git a/apps/frontend/src/app/backups-overview/component/backups.component.css b/apps/frontend/src/app/backups-overview/component/backups.component.css deleted file mode 100644 index db506bc0..00000000 --- a/apps/frontend/src/app/backups-overview/component/backups.component.css +++ /dev/null @@ -1,178 +0,0 @@ -.header { - background-color: white; - justify-content: space-around; - position: relative; -} - -.filter-inline { - display: inline-flex !important; - align-items: center; -} - -.alert-info-section { - display: flex; - gap: 40px; - margin: 20px 0; - align-items: center; - position: relative; -} - -.alert-panel, -.info { - flex: 1; -} - -.card { - position: relative; - z-index: 1; -} - -.card-block { - padding: 20px; -} - -.clr-form-control { - margin-top: 0; -} - -.card-header { - display: flex; - justify-content: space-between; - align-items: center; -} - -.card-header-title { - margin: 0; - font-weight: 500; -} - -.card-header-actions { - display: flex; - align-items: center; -} - -:host ::ng-deep .card-header { - border-bottom: none !important; -} - -.btn-group-vertical { - display: flex; - flex-direction: column; - align-items: center; - width: 100%; -} - -.btn-group-vertical .btn { - border: 1px solid #0072a3; - color: #0072a3; - background: white; - text-align: center; - padding: 0.5rem 1rem; - font-weight: 500; - width: 100%; - border-radius: 0.15rem; -} - -.btn-group-vertical .btn.btn-primary { - background: #0072a3; - color: white; -} -.clr-side-panel { - width: 80% !important; - padding: 0.5rem; - border: 1px solid #ccc; - border-radius: 0.15rem; - background: white; - color: #1b2834; - font-size: 0.875rem; - right: 0; - top: 0; - height: 100vh; - z-index: 1000000; - box-shadow: -2px 0 8px rgba(0, 0, 0, 0.1); -} -.modal { - z-index: 1000000; -} - -.side-panel-footer { - padding: 1rem; - border-top: 1px solid #eee; - position: absolute; - bottom: 0; - left: 0; - right: 0; - background: white; -} - -.backupTaskFilter { - margin-top: 0.8rem; - width: 100%; -} - -.backupTaskFilter ::ng-deep .clr-combobox-wrapper { - width: 100%; - border: 1px solid #0072a3; - border-radius: 0.15rem; - background: white; - padding: 10px 15px; -} - -.backupTaskFilter ::ng-deep .clr-combobox-input { - width: 100%; - padding: 0.5rem 1rem; - color: #0072a3; - font-weight: 500; - border: none; - background: white; -} - -.backupTaskFilter ::ng-deep .clr-combobox-trigger { - color: #0072a3; - border: none; - background: none; - padding-right: 0.5rem; - top: unset; -} - -.backupTaskFilter ::ng-deep .clr-combobox-options { - border: 1px solid #0072a3; - border-radius: 0.15rem; - margin-top: 0.25rem; -} - -.backupTaskFilter ::ng-deep .clr-combobox-options .clr-combobox-option { - padding: 0.5rem 1rem; - color: #0072a3; - font-weight: 500; -} - -.backupTaskFilter ::ng-deep .clr-combobox-options .clr-combobox-option:hover { - background: #0072a3; - color: white; -} - -.backupTaskFilter - ::ng-deep - .clr-combobox-options - .clr-combobox-option[aria-selected='true'] { - background: #0072a3; - color: white; -} - -.backupTaskFilter ::ng-deep .clr-combobox-wrapper .label-combobox-pill { - max-width: none; - font-size: 0.7rem; - padding: 0.15rem 0.5rem; - margin: 0.15rem; - white-space: nowrap; - height: auto; - line-height: 1; -} - - -.backupTaskFilter ::ng-deep .clr-combobox-options { - width: 100% !important; - min-width: 100%; - max-width: 100%; -} diff --git a/apps/frontend/src/app/backups-overview/component/information-panel/information-panel.component.html b/apps/frontend/src/app/backups-overview/component/information-panel/information-panel.component.html deleted file mode 100644 index fb9eb1b3..00000000 --- a/apps/frontend/src/app/backups-overview/component/information-panel/information-panel.component.html +++ /dev/null @@ -1,32 +0,0 @@ -
-
-
-

On this page, you can:

-
    -
  • - See Alerts: View the current status and details of - any alerts that have been triggered. Alerts are categorized by their - severity. -
  • -
  • - See all backups with basic data: Browse through a - list of all backups, including essential information such as Backup - ID, size and creation date. -
  • -
  • - See how the size of the backup evolved over time: - Visualize the changes in backup sizes over time through the - Recent Backup Timeline chart, helping you - understand the growth and trends in your backup data. -
  • -
  • - See Recent Backup Size Distribution: Analyze the - recent distribution of backup sizes through the - Recent Backup Size Distribution chart. -
  • -
- -

More insights will follow.

-
-
-
\ No newline at end of file diff --git a/apps/frontend/src/app/management/components/settings/notification-settings/notification-settings.component.ts b/apps/frontend/src/app/management/components/settings/notification-settings/notification-settings.component.ts index 3da3d0a7..2a46bc8a 100644 --- a/apps/frontend/src/app/management/components/settings/notification-settings/notification-settings.component.ts +++ b/apps/frontend/src/app/management/components/settings/notification-settings/notification-settings.component.ts @@ -3,7 +3,7 @@ import { FormArray, FormBuilder, FormGroup } from '@angular/forms'; import { BehaviorSubject, forkJoin, Subject, takeUntil } from 'rxjs'; import { NotificationService } from '../../../services/alert-notification/notification.service'; import { AlertType } from '../../../../shared/types/alertType'; -import { AlertServiceService } from '../../../../alert/service/alert-service.service'; +import { AlertServiceService } from '../../../../shared/services/alert-service/alert-service.service'; @Component({ selector: 'app-notification-settings', diff --git a/apps/frontend/src/app/backups-overview/component/side-panel/side-panel.component.css b/apps/frontend/src/app/shared/components/filter-side-panel/side-panel.component.css similarity index 100% rename from apps/frontend/src/app/backups-overview/component/side-panel/side-panel.component.css rename to apps/frontend/src/app/shared/components/filter-side-panel/side-panel.component.css diff --git a/apps/frontend/src/app/backups-overview/component/side-panel/side-panel.component.html b/apps/frontend/src/app/shared/components/filter-side-panel/side-panel.component.html similarity index 100% rename from apps/frontend/src/app/backups-overview/component/side-panel/side-panel.component.html rename to apps/frontend/src/app/shared/components/filter-side-panel/side-panel.component.html diff --git a/apps/frontend/src/app/backups-overview/component/side-panel/side-panel.component.spec.ts b/apps/frontend/src/app/shared/components/filter-side-panel/side-panel.component.spec.ts similarity index 93% rename from apps/frontend/src/app/backups-overview/component/side-panel/side-panel.component.spec.ts rename to apps/frontend/src/app/shared/components/filter-side-panel/side-panel.component.spec.ts index 27d1c34c..a1b16c9a 100644 --- a/apps/frontend/src/app/backups-overview/component/side-panel/side-panel.component.spec.ts +++ b/apps/frontend/src/app/shared/components/filter-side-panel/side-panel.component.spec.ts @@ -2,13 +2,13 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; import { TestBed } from '@angular/core/testing'; import { of } from 'rxjs'; import { SidePanelComponent } from './side-panel.component'; -import { APIResponse } from '../../../shared/types/api-response'; -import { Backup } from '../../../shared/types/backup'; -import { BackupType } from '../../../shared/enums/backup.types'; -import { ChartService } from '../../service/chart-service/chart-service.service'; -import { BackupService } from '../../service/backup-service/backup-service.service'; -import { BackupTask } from '../../../shared/types/backup.task'; -import { ChartType } from '../../../shared/enums/chartType'; +import { APIResponse } from '../../types/api-response'; +import { Backup } from '../../types/backup'; +import { BackupType } from '../../enums/backup.types'; +import { ChartService } from '../../services/chart-service/chart-service.service'; +import { BackupService } from '../../services/backup-service/backup-service.service'; +import { BackupTask } from '../../types/backup.task'; +import { ChartType } from '../../enums/chartType'; describe('SidePanelComponent', () => { let component: SidePanelComponent; diff --git a/apps/frontend/src/app/backups-overview/component/side-panel/side-panel.component.ts b/apps/frontend/src/app/shared/components/filter-side-panel/side-panel.component.ts similarity index 93% rename from apps/frontend/src/app/backups-overview/component/side-panel/side-panel.component.ts rename to apps/frontend/src/app/shared/components/filter-side-panel/side-panel.component.ts index 8fd60d41..05104b06 100644 --- a/apps/frontend/src/app/backups-overview/component/side-panel/side-panel.component.ts +++ b/apps/frontend/src/app/shared/components/filter-side-panel/side-panel.component.ts @@ -5,7 +5,7 @@ import { OnDestroy, OnInit, } from '@angular/core'; -import { BackupType } from '../../../shared/enums/backup.types'; +import { BackupType } from '../../enums/backup.types'; import { BehaviorSubject, combineLatest, @@ -20,13 +20,13 @@ import { takeUntil, tap, } from 'rxjs'; -import { BackupTask } from '../../../shared/types/backup.task'; -import { BackupService } from '../../service/backup-service/backup-service.service'; -import { ChartService } from '../../service/chart-service/chart-service.service'; -import { Backup } from '../../../shared/types/backup'; -import { APIResponse } from '../../../shared/types/api-response'; -import { ChartInformation } from '../../../shared/types/chartInformation'; -import { ChartType } from '../../../shared/enums/chartType'; +import { BackupTask } from '../../types/backup.task'; +import { BackupService } from '../../services/backup-service/backup-service.service'; +import { ChartService } from '../../services/chart-service/chart-service.service'; +import { Backup } from '../../types/backup'; +import { APIResponse } from '../../types/api-response'; +import { ChartInformation } from '../../types/chartInformation'; +import { ChartType } from '../../enums/chartType'; interface TimeRangeConfig { fromDate: Date; diff --git a/apps/frontend/src/app/alert/service/alert-service.service.spec.ts b/apps/frontend/src/app/shared/services/alert-service/alert-service.service.spec.ts similarity index 89% rename from apps/frontend/src/app/alert/service/alert-service.service.spec.ts rename to apps/frontend/src/app/shared/services/alert-service/alert-service.service.spec.ts index 3ef00e32..6ff5ff20 100644 --- a/apps/frontend/src/app/alert/service/alert-service.service.spec.ts +++ b/apps/frontend/src/app/shared/services/alert-service/alert-service.service.spec.ts @@ -4,13 +4,13 @@ import { HttpTestingController, } from '@angular/common/http/testing'; import { AlertServiceService } from './alert-service.service'; -import { BASE_URL } from '../../shared/types/configuration'; -import { Alert } from '../../shared/types/alert'; +import { BASE_URL } from '../../types/configuration'; +import { Alert } from '../../types/alert'; import { describe, it, expect, beforeEach } from 'vitest'; -import { AlertType } from '../../shared/types/alertType'; -import { BackupService } from '../../backups-overview/service/backup-service/backup-service.service'; +import { AlertType } from '../../types/alertType'; +import { BackupService } from '../backup-service/backup-service.service'; import { randomUUID } from 'node:crypto'; -import { SeverityType } from '../../shared/enums/severityType'; +import { SeverityType } from '../../enums/severityType'; describe('AlertServiceService', () => { let service: AlertServiceService; diff --git a/apps/frontend/src/app/alert/service/alert-service.service.ts b/apps/frontend/src/app/shared/services/alert-service/alert-service.service.ts similarity index 86% rename from apps/frontend/src/app/alert/service/alert-service.service.ts rename to apps/frontend/src/app/shared/services/alert-service/alert-service.service.ts index 701e62a1..78dfe753 100644 --- a/apps/frontend/src/app/alert/service/alert-service.service.ts +++ b/apps/frontend/src/app/shared/services/alert-service/alert-service.service.ts @@ -1,8 +1,8 @@ import { Inject, Injectable } from '@angular/core'; -import { BASE_URL } from '../../shared/types/configuration'; +import { BASE_URL } from '../../types/configuration'; import { HttpClient } from '@angular/common/http'; import { Observable, Subject } from 'rxjs'; -import { Alert } from '../../shared/types/alert'; +import { Alert } from '../../types/alert'; @Injectable({ providedIn: 'root', diff --git a/apps/frontend/src/app/backups-overview/service/backup-service/backup-service.service.spec.ts b/apps/frontend/src/app/shared/services/backup-service/backup-service.service.spec.ts similarity index 92% rename from apps/frontend/src/app/backups-overview/service/backup-service/backup-service.service.spec.ts rename to apps/frontend/src/app/shared/services/backup-service/backup-service.service.spec.ts index f318d42e..3d4311a0 100644 --- a/apps/frontend/src/app/backups-overview/service/backup-service/backup-service.service.spec.ts +++ b/apps/frontend/src/app/shared/services/backup-service/backup-service.service.spec.ts @@ -3,10 +3,10 @@ import { HttpClient, HttpParams } from '@angular/common/http'; import { of, throwError } from 'rxjs'; import { BackupService } from './backup-service.service'; -import { APIResponse } from '../../../shared/types/api-response'; -import { Backup } from '../../../shared/types/backup'; -import { BackupFilterParams } from '../../../shared/types/backup-filter-type'; -import { BackupTask } from '../../../shared/types/backup.task'; +import { APIResponse } from '../../types/api-response'; +import { Backup } from '../../types/backup'; +import { BackupFilterParams } from '../../types/backup-filter-type'; +import { BackupTask } from '../../types/backup.task'; import { fail } from 'assert'; describe('BackupService', () => { diff --git a/apps/frontend/src/app/backups-overview/service/backup-service/backup-service.service.ts b/apps/frontend/src/app/shared/services/backup-service/backup-service.service.ts similarity index 80% rename from apps/frontend/src/app/backups-overview/service/backup-service/backup-service.service.ts rename to apps/frontend/src/app/shared/services/backup-service/backup-service.service.ts index c3dfa732..3885386a 100644 --- a/apps/frontend/src/app/backups-overview/service/backup-service/backup-service.service.ts +++ b/apps/frontend/src/app/shared/services/backup-service/backup-service.service.ts @@ -1,11 +1,11 @@ import { HttpClient, HttpParams } from '@angular/common/http'; import { Inject, Injectable } from '@angular/core'; import { Observable, shareReplay } from 'rxjs'; -import { BASE_URL } from '../../../shared/types/configuration'; -import { Backup } from '../../../shared/types/backup'; -import { APIResponse } from '../../../shared/types/api-response'; -import { BackupFilterParams } from '../../../shared/types/backup-filter-type'; -import { BackupTask } from '../../../shared/types/backup.task'; +import { BASE_URL } from '../../types/configuration'; +import { Backup } from '../../types/backup'; +import { APIResponse } from '../../types/api-response'; +import { BackupFilterParams } from '../../types/backup-filter-type'; +import { BackupTask } from '../../types/backup.task'; @Injectable({ providedIn: 'root', diff --git a/apps/frontend/src/app/backups-overview/service/chart-service/chart-service.service.spec.ts b/apps/frontend/src/app/shared/services/chart-service/chart-service.service.spec.ts similarity index 98% rename from apps/frontend/src/app/backups-overview/service/chart-service/chart-service.service.spec.ts rename to apps/frontend/src/app/shared/services/chart-service/chart-service.service.spec.ts index 4bd5a718..d6b6b394 100644 --- a/apps/frontend/src/app/backups-overview/service/chart-service/chart-service.service.spec.ts +++ b/apps/frontend/src/app/shared/services/chart-service/chart-service.service.spec.ts @@ -2,7 +2,7 @@ import { describe, it, expect, beforeEach, vi } from 'vitest'; import { ChartService } from './chart-service.service'; import * as am5 from '@amcharts/amcharts5'; import { of } from 'rxjs'; -import type { ChartConfig } from '../../../shared/types/chart-config'; +import type { ChartConfig } from '../../types/chart-config'; Object.defineProperty(HTMLCanvasElement.prototype, 'getContext', { value: () => ({ diff --git a/apps/frontend/src/app/backups-overview/service/chart-service/chart-service.service.ts b/apps/frontend/src/app/shared/services/chart-service/chart-service.service.ts similarity index 99% rename from apps/frontend/src/app/backups-overview/service/chart-service/chart-service.service.ts rename to apps/frontend/src/app/shared/services/chart-service/chart-service.service.ts index 3416d63b..bdb4f855 100644 --- a/apps/frontend/src/app/backups-overview/service/chart-service/chart-service.service.ts +++ b/apps/frontend/src/app/shared/services/chart-service/chart-service.service.ts @@ -5,13 +5,13 @@ import * as am5xy from '@amcharts/amcharts5/xy'; import * as am5percent from '@amcharts/amcharts5/percent'; import am5themes_Animated from '@amcharts/amcharts5/themes/Animated'; import { ITimeInterval } from '@amcharts/amcharts5/.internal/core/util/Time'; -import { Backup } from '../../../shared/types/backup'; +import { Backup } from '../../types/backup'; import { Observable, Subject, takeUntil } from 'rxjs'; import { ChartConfig, ChartType, TimeRange, -} from '../../../shared/types/chart-config'; +} from '../../types/chart-config'; @Injectable({ providedIn: 'root', diff --git a/apps/frontend/src/app/data-stores/service/data-stores-service.service.spec.ts b/apps/frontend/src/app/shared/services/data-stores-service/data-stores-service.service.spec.ts similarity index 97% rename from apps/frontend/src/app/data-stores/service/data-stores-service.service.spec.ts rename to apps/frontend/src/app/shared/services/data-stores-service/data-stores-service.service.spec.ts index 41082d42..d436a8af 100644 --- a/apps/frontend/src/app/data-stores/service/data-stores-service.service.spec.ts +++ b/apps/frontend/src/app/shared/services/data-stores-service/data-stores-service.service.spec.ts @@ -4,7 +4,7 @@ import { of, throwError } from 'rxjs'; import { fail } from 'assert'; import { DataStoresService } from './data-stores-service.service'; -import { DataStore } from '../../shared/types/data-store'; +import { DataStore } from '../../types/data-store'; describe('BackupService', () => { let service: DataStoresService; diff --git a/apps/frontend/src/app/data-stores/service/data-stores-service.service.ts b/apps/frontend/src/app/shared/services/data-stores-service/data-stores-service.service.ts similarity index 78% rename from apps/frontend/src/app/data-stores/service/data-stores-service.service.ts rename to apps/frontend/src/app/shared/services/data-stores-service/data-stores-service.service.ts index 5e5a0103..53618039 100644 --- a/apps/frontend/src/app/data-stores/service/data-stores-service.service.ts +++ b/apps/frontend/src/app/shared/services/data-stores-service/data-stores-service.service.ts @@ -1,8 +1,8 @@ import { HttpClient } from '@angular/common/http'; import { Inject, Injectable } from '@angular/core'; import { Observable } from 'rxjs'; -import { DataStore } from '../../shared/types/data-store'; -import { BASE_URL } from '../../shared/types/configuration'; +import { DataStore } from '../../types/data-store'; +import { BASE_URL } from '../../types/configuration'; @Injectable({ providedIn: 'root',