From 07808822f76a611a891f366cc5b7aec8502dce24 Mon Sep 17 00:00:00 2001 From: sepehr Date: Thu, 16 Oct 2025 17:34:19 +0300 Subject: [PATCH] feat: redesign backups management interface - Complete UI/UX redesign of backups module - Improved backup viewing and management - Enhanced backup operations interface - Better backup history and restoration --- src/app/views/backups/backups.component.html | 248 +++++++++++++------ src/app/views/backups/backups.component.scss | 65 +++++ src/app/views/backups/backups.component.ts | 74 ++++-- src/app/views/backups/backups.module.ts | 3 +- 4 files changed, 298 insertions(+), 92 deletions(-) diff --git a/src/app/views/backups/backups.component.html b/src/app/views/backups/backups.component.html index 2ccdd5e..cd82daa 100644 --- a/src/app/views/backups/backups.component.html +++ b/src/app/views/backups/backups.component.html @@ -2,58 +2,97 @@ - - - Backups Filtered Result For Device ID {{devid}} + + +
+
Backups
+ + Device ID {{devid}} + +
- - - - -
- {{item.id}}:{{item.devname}} {{item.createdC}} X + +
+ +
+
+ + {{compareitems.length}} Selected + +
+ + {{item.devname}} + +
- - - - - - - - - + + +
+
+ + +
- -
- - - Start date - - - - - - End date - - - - - - Config search - - - -
-
+ +
+ + + + +
+ + + + + + +
+
+ +
+ + + + + + +
+
+ +
+ + + + +
+
+
+
+
+
@@ -87,13 +126,29 @@ {{value}} - + - - +
+ + + +
@@ -164,31 +219,80 @@ + - -
Please Confirm Action
+ +
Confirm Backup Restore
- - restore backup ? - - Are you sure that You want to Restore this configuration on - device?
-
-

- All Current device configuration will be reset:

- * All state data/history on router will be reset
- * All other local users on router will be deleted
- * After restore the password of the local user will be same as configured in MikroWizard
-

-
+ +
+ +
Restore Configuration Backup
+
+ +
+
Backup Details
+
+
Device: {{currentBackup?.devname}}
+
IP: {{currentBackup?.devip}}
+
Date: {{currentBackup?.createdC}}
+
Size: {{currentBackup?.filesize}}
+
+
+ + +
Critical Warning
+

This action will completely reset the device configuration:

+
    +
  • All current device configuration will be overwritten
  • +
  • All state data and history on router will be reset
  • +
  • All other local users on router will be deleted
  • +
  • Device will reboot and apply the restored configuration
  • +
+
- - - + +
+ + + + +
CRITICAL: Final Confirmation Required
+
+ +
+ +
DESTRUCTIVE ACTION
+

You are about to permanently overwrite device configuration

+
+ +
+

To proceed with this critical action, type CONFIRM in the box below:

+ +
+ + + + This confirmation ensures you understand the critical nature of this operation. + + +
+ + +
diff --git a/src/app/views/backups/backups.component.scss b/src/app/views/backups/backups.component.scss index ef17e02..16b7298 100644 --- a/src/app/views/backups/backups.component.scss +++ b/src/app/views/backups/backups.component.scss @@ -1,7 +1,72 @@ @import 'ngx-diff/styles/default-theme'; + ::ng-deep .modal-xl { --cui-modal-width: 90vw!important; } + ::ng-deep pre { display: block!important; +} + +// Enhanced UI Styles +.compare-panel { + background: rgba(13, 110, 253, 0.1); + border: 1px solid rgba(13, 110, 253, 0.2); + border-radius: 0.375rem; + padding: 0.5rem; +} + +.selected-item { + font-size: 0.75rem; + + .fa-times { + font-size: 0.7rem; + opacity: 0.7; + transition: opacity 0.2s; + + &:hover { + opacity: 1; + } + } +} + +.cursor-pointer { + cursor: pointer; +} + +.filter-group { + .form-label { + font-size: 0.875rem; + color: #495057; + } + + ::ng-deep .mat-mdc-form-field { + .mat-mdc-text-field-wrapper { + background-color: white; + } + } +} + +.confirmation-box { + input { + font-size: 1.1rem; + + &:focus { + border-color: #dc3545; + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25); + } + } +} + +// Action buttons spacing +.d-flex.gap-1 { + gap: 0.25rem !important; +} + +// Backup info styling +.backup-info { + .row > div { + margin-bottom: 0.5rem; + font-size: 0.9rem; + } } \ No newline at end of file diff --git a/src/app/views/backups/backups.component.ts b/src/app/views/backups/backups.component.ts index 24409fc..68a0b62 100644 --- a/src/app/views/backups/backups.component.ts +++ b/src/app/views/backups/backups.component.ts @@ -30,11 +30,13 @@ export class BackupsComponent implements OnInit { public codeForHighlightAuto: string = ""; public ispro: boolean = false; public ConfirmModalVisible: boolean = false; + public CriticalConfirmModalVisible: boolean = false; public CompareModalVisible: boolean = false; public compareitems:any=[]; public comparecontents:any=[]; public compare_type="unified"; public copy_msg:boolean=false; + public confirmationText: string = ''; constructor( private data_provider: dataProvider, @@ -186,31 +188,55 @@ export class BackupsComponent implements OnInit { this.filters_visible = !this.filters_visible; } - restore_backup(apply:boolean=false){ - var _slef=this; - if (!apply){ + restore_backup(apply: boolean = false, doubleConfirmed: boolean = false, backup?: any) { + var _self = this; + + // Set current backup if provided + if (backup) { + this.currentBackup = backup; + } + + if (!apply) { + // Step 1: Show initial confirmation this.ConfirmModalVisible = true; return; } - if (!this.currentBackup) + + if (!this.currentBackup) { return; - if(apply){ - _slef.ConfirmModalVisible = false; - _slef.BakcupModalVisible = true; - this.show_toast('Success', 'Backup restored successfully', 'success') - this.show_toast('Info', 'Wait for the router to reboot and apply config', 'info') + } + + if (apply && !doubleConfirmed) { + // Step 2: Show critical confirmation + this.ConfirmModalVisible = false; + this.CriticalConfirmModalVisible = true; + this.confirmationText = ''; + return; + } + + if (apply && doubleConfirmed) { + // Step 3: Execute restore + _self.CriticalConfirmModalVisible = false; + _self.BakcupModalVisible = false; + this.data_provider.restore_backup(this.currentBackup.id).then((res) => { - if ('status' in res){ - if(res['status']=='success'){ - this.show_toast('Success', 'Backup restored successfully', 'success') - this.show_toast('Info', 'Wait for the router to reboot and apply config', 'info') + if ('status' in res) { + if (res['status'] == 'success') { + this.show_toast('Success', 'Backup restored successfully', 'success'); + this.show_toast('Info', 'Wait for the router to reboot and apply config', 'info'); + } else { + this.show_toast('Error', 'Error restoring backup', 'danger'); } - else - this.show_toast('Error', 'Error restoring backup', 'danger') } }); } } + + cancelCriticalRestore() { + this.CriticalConfirmModalVisible = false; + this.confirmationText = ''; + this.currentBackup = null; + } start_compare(){ var _self=this; @@ -243,10 +269,20 @@ export class BackupsComponent implements OnInit { this.compareitems.push(item); } } - delete_compare(i:number){ - //delete item index i from compareitems - this.compareitems.splice(i,1); - + delete_compare(i: number) { + // Delete item index i from compareitems + this.compareitems.splice(i, 1); + } + + clearAllCompare() { + // Clear all compare items + this.compareitems = []; + this.comparecontents = []; + } + + isInCompareList(item: any): boolean { + // Check if item is already in compare list + return this.compareitems.some((compareItem: any) => compareItem.id === item.id); } reinitgrid(field: string, $event: any) { if (field == "start") this.filters["start_time"] = $event.target.value; diff --git a/src/app/views/backups/backups.module.ts b/src/app/views/backups/backups.module.ts index 9d6d18c..b24187a 100644 --- a/src/app/views/backups/backups.module.ts +++ b/src/app/views/backups/backups.module.ts @@ -12,6 +12,7 @@ import { ModalModule, FormModule, ToastModule, + AlertModule, } from "@coreui/angular"; import { BackupsRoutingModule } from "./backups-routing.module"; @@ -34,10 +35,10 @@ import { ClipboardModule } from "@angular/cdk/clipboard"; FormModule, FormsModule, ButtonModule, - ButtonModule, GuiGridModule, CollapseModule, BadgeModule, + AlertModule, Highlight, HighlightAuto, HighlightLineNumbers,