mirror of
https://github.com/MikroWizard/mikrofront.git
synced 2025-12-08 11:09:29 +00:00
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
This commit is contained in:
parent
069e53cec6
commit
07808822f7
4 changed files with 298 additions and 92 deletions
|
|
@ -2,58 +2,97 @@
|
||||||
<c-col xs>
|
<c-col xs>
|
||||||
<c-card class="mb-4">
|
<c-card class="mb-4">
|
||||||
<c-card-header>
|
<c-card-header>
|
||||||
<c-row>
|
<c-row class="align-items-center">
|
||||||
<c-col xs [lg]="8">
|
<c-col xs [lg]="6">
|
||||||
Backups <c-badge color="warning" *ngIf="devid!=0">Filtered Result For Device ID {{devid}}</c-badge>
|
<div class="d-flex align-items-center">
|
||||||
|
<h5 class="mb-0 me-3"><i class="fa-solid fa-database me-2"></i>Backups</h5>
|
||||||
|
<c-badge color="warning" *ngIf="devid!=0" class="fs-6">
|
||||||
|
<i class="fa-solid fa-filter me-1"></i>Device ID {{devid}}
|
||||||
|
</c-badge>
|
||||||
|
</div>
|
||||||
</c-col>
|
</c-col>
|
||||||
<c-col xs [lg]="3">
|
<c-col xs [lg]="6">
|
||||||
<c-row>
|
<div class="d-flex justify-content-end align-items-center gap-2">
|
||||||
<c-col>
|
<!-- Compare Selection Panel -->
|
||||||
<ng-container *ngIf="compareitems.length>0">
|
<div *ngIf="compareitems.length > 0" class="compare-panel me-2">
|
||||||
<div>
|
<div class="d-flex align-items-center gap-2">
|
||||||
<c-badge color="dark" style="font-size: 0.7rem;"
|
<c-badge color="info" class="fs-6">
|
||||||
*ngFor="let item of compareitems;index as i">{{item.id}}:{{item.devname}} {{item.createdC}} <span
|
<i class="fa-solid fa-code-compare me-1"></i>{{compareitems.length}} Selected
|
||||||
style="cursor: pointer;" (click)="delete_compare(i)">X</span></c-badge>
|
</c-badge>
|
||||||
|
<div class="selected-items d-flex gap-1">
|
||||||
|
<c-badge color="secondary" *ngFor="let item of compareitems; index as i"
|
||||||
|
class="selected-item d-flex align-items-center">
|
||||||
|
<span class="me-1">{{item.devname}}</span>
|
||||||
|
<i class="fa-solid fa-times cursor-pointer" (click)="delete_compare(i)"
|
||||||
|
title="Remove from comparison"></i>
|
||||||
|
</c-badge>
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
<button *ngIf="compareitems.length > 1" (click)="start_compare()"
|
||||||
</c-col>
|
cButton color="success" size="sm">
|
||||||
<c-col style="padding: 0;">
|
<i class="fa-solid fa-code-compare me-1"></i>Compare
|
||||||
<button *ngIf="compareitems.length>1" (click)="start_compare()" cButton class="me-1"
|
</button>
|
||||||
color="primary">Compare</button>
|
<button (click)="clearAllCompare()" cButton color="secondary" size="sm" variant="outline">
|
||||||
</c-col>
|
<i class="fa-solid fa-trash me-1"></i>Clear
|
||||||
</c-row>
|
</button>
|
||||||
</c-col>
|
</div>
|
||||||
<c-col styyle="border-left: 1px solid #ccc;" xs [lg]="1">
|
</div>
|
||||||
<button (click)="toggleCollapse()" cButton class="me-1" color="primary"><i
|
<!-- Filter Toggle -->
|
||||||
class="fa-solid fa-filter mr-1"></i>Filter</button>
|
<button (click)="toggleCollapse()" cButton color="primary" variant="outline">
|
||||||
|
<i class="fa-solid fa-filter me-1"></i>Filters
|
||||||
|
<i class="fa-solid" [class]="filters_visible ? 'fa-chevron-up' : 'fa-chevron-down'"
|
||||||
|
style="margin-left: 0.5rem; font-size: 0.8rem;"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</c-col>
|
</c-col>
|
||||||
</c-row>
|
</c-row>
|
||||||
</c-card-header>
|
</c-card-header>
|
||||||
<c-card-body>
|
<c-card-body>
|
||||||
<c-row>
|
<!-- Enhanced Filter Panel -->
|
||||||
<div [visible]="filters_visible" cCollapse>
|
<div [visible]="filters_visible" cCollapse class="mb-3">
|
||||||
<c-col xs [lg]="12" class="example-form">
|
<c-card class="border-0 bg-light">
|
||||||
<mat-form-field>
|
<c-card-body class="py-3">
|
||||||
<mat-label>Start date</mat-label>
|
<c-row class="g-3 align-items-end">
|
||||||
<input matInput [matDatepicker]="picker1" (dateChange)="reinitgrid('start',$event)"
|
<c-col xs="12" md="4">
|
||||||
[(ngModel)]="filters['start_time']" />
|
<div class="filter-group">
|
||||||
<mat-datepicker-toggle matIconSuffix [for]="picker1"></mat-datepicker-toggle>
|
<label class="form-label fw-semibold mb-2">
|
||||||
<mat-datepicker #picker1></mat-datepicker>
|
<i class="fa-solid fa-calendar-days me-1 text-primary"></i>Start Date
|
||||||
</mat-form-field>
|
</label>
|
||||||
<mat-form-field>
|
<mat-form-field appearance="outline" class="w-100">
|
||||||
<mat-label>End date</mat-label>
|
<input matInput [matDatepicker]="picker1" (dateChange)="reinitgrid('start',$event)"
|
||||||
<input matInput [matDatepicker]="picker2" (dateChange)="reinitgrid('end',$event)"
|
[(ngModel)]="filters['start_time']" placeholder="Select start date" />
|
||||||
[(ngModel)]="filters['end_time']" />
|
<mat-datepicker-toggle matIconSuffix [for]="picker1"></mat-datepicker-toggle>
|
||||||
<mat-datepicker-toggle matIconSuffix [for]="picker2"></mat-datepicker-toggle>
|
<mat-datepicker #picker1></mat-datepicker>
|
||||||
<mat-datepicker #picker2></mat-datepicker>
|
</mat-form-field>
|
||||||
</mat-form-field>
|
</div>
|
||||||
<mat-form-field *ngIf="ispro">
|
</c-col>
|
||||||
<mat-label>Config search</mat-label>
|
<c-col xs="12" md="4">
|
||||||
<input (ngModelChange)="reinitgrid('search',$event)" [(ngModel)]="filters['search']" matInput>
|
<div class="filter-group">
|
||||||
</mat-form-field>
|
<label class="form-label fw-semibold mb-2">
|
||||||
</c-col>
|
<i class="fa-solid fa-calendar-days me-1 text-primary"></i>End Date
|
||||||
</div>
|
</label>
|
||||||
</c-row>
|
<mat-form-field appearance="outline" class="w-100">
|
||||||
|
<input matInput [matDatepicker]="picker2" (dateChange)="reinitgrid('end',$event)"
|
||||||
|
[(ngModel)]="filters['end_time']" placeholder="Select end date" />
|
||||||
|
<mat-datepicker-toggle matIconSuffix [for]="picker2"></mat-datepicker-toggle>
|
||||||
|
<mat-datepicker #picker2></mat-datepicker>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
</c-col>
|
||||||
|
<c-col xs="12" md="4" *ngIf="ispro">
|
||||||
|
<div class="filter-group">
|
||||||
|
<label class="form-label fw-semibold mb-2">
|
||||||
|
<i class="fa-solid fa-magnifying-glass me-1 text-primary"></i>Config Search
|
||||||
|
</label>
|
||||||
|
<mat-form-field appearance="outline" class="w-100">
|
||||||
|
<input (ngModelChange)="reinitgrid('search',$event)" [(ngModel)]="filters['search']"
|
||||||
|
matInput placeholder="Search in configurations...">
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
</c-col>
|
||||||
|
</c-row>
|
||||||
|
</c-card-body>
|
||||||
|
</c-card>
|
||||||
|
</div>
|
||||||
<gui-grid [source]="source" [paging]="paging" [columnMenu]="columnMenu" [sorting]="sorting"
|
<gui-grid [source]="source" [paging]="paging" [columnMenu]="columnMenu" [sorting]="sorting"
|
||||||
[infoPanel]="infoPanel" [columnMenu]="columnMenu" [sorting]="sorting" [infoPanel]="infoPanel"
|
[infoPanel]="infoPanel" [columnMenu]="columnMenu" [sorting]="sorting" [infoPanel]="infoPanel"
|
||||||
[autoResizeWidth]=true>
|
[autoResizeWidth]=true>
|
||||||
|
|
@ -87,13 +126,29 @@
|
||||||
{{value}}
|
{{value}}
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</gui-grid-column>
|
</gui-grid-column>
|
||||||
<gui-grid-column header="Action" field="id">
|
<gui-grid-column header="Actions" field="id" width="280">
|
||||||
<ng-template let-value="item.id" let-item="item" let-index="index">
|
<ng-template let-value="item.id" let-item="item" let-index="index">
|
||||||
<button cButton [disabled]="backuploading" color="info" size="sm" (click)="ShowBackup(item)" class="mx-1">
|
<div class="d-flex gap-1">
|
||||||
<i *ngIf="backuploading" style="margin: 1px 5px;color:#ffffff;" class="fa-solid fa-spinner fa-spin"></i>
|
<button cButton [disabled]="backuploading" color="primary" size="sm"
|
||||||
<i *ngIf="!backuploading" style="margin: 1px 5px;color:#ffffff;" class="fa-solid fa-eye"></i>Show backup</button>
|
(click)="ShowBackup(item)" variant="outline" title="View backup content">
|
||||||
<button *ngIf="ispro" cButton color="info" size="sm" (click)="add_for_compare(item)" class="mx-1"><i
|
<i *ngIf="backuploading && currentBackup?.id === item.id"
|
||||||
style="margin: 1px 5px;color:#ffffff;" class="fa-solid fa-eye"></i>Compare</button>
|
class="fa-solid fa-spinner fa-spin me-1"></i>
|
||||||
|
<i *ngIf="!backuploading || currentBackup?.id !== item.id"
|
||||||
|
class="fa-solid fa-eye me-1"></i>
|
||||||
|
View
|
||||||
|
</button>
|
||||||
|
<button *ngIf="ispro" cButton color="info" size="sm" variant="outline"
|
||||||
|
(click)="add_for_compare(item)" title="Add to comparison"
|
||||||
|
[disabled]="isInCompareList(item)">
|
||||||
|
<i class="fa-solid fa-code-compare me-1"></i>
|
||||||
|
{{isInCompareList(item) ? 'Added' : 'Compare'}}
|
||||||
|
</button>
|
||||||
|
<button *ngIf="ispro" cButton color="warning" size="sm" variant="outline"
|
||||||
|
(click)="restore_backup(false, false, item)" title="Restore this backup">
|
||||||
|
<i class="fa-solid fa-rotate-left me-1"></i>
|
||||||
|
Restore
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</gui-grid-column>
|
</gui-grid-column>
|
||||||
</gui-grid>
|
</gui-grid>
|
||||||
|
|
@ -164,31 +219,80 @@
|
||||||
</c-modal-footer>
|
</c-modal-footer>
|
||||||
</c-modal>
|
</c-modal>
|
||||||
|
|
||||||
|
<!-- Initial Restore Confirmation -->
|
||||||
<c-modal #ConfirmModal backdrop="static" [(visible)]="ConfirmModalVisible" id="runConfirmModal">
|
<c-modal #ConfirmModal backdrop="static" [(visible)]="ConfirmModalVisible" id="runConfirmModal">
|
||||||
<c-modal-header>
|
<c-modal-header class="bg-warning text-dark">
|
||||||
<h6 cModalTitle>Please Confirm Action </h6>
|
<h5 cModalTitle><i class="fa-solid fa-exclamation-triangle me-2"></i>Confirm Backup Restore</h5>
|
||||||
<button [cModalToggle]="ConfirmModal.id" cButtonClose></button>
|
<button [cModalToggle]="ConfirmModal.id" cButtonClose></button>
|
||||||
</c-modal-header>
|
</c-modal-header>
|
||||||
<c-modal-body>
|
<c-modal-body class="p-4">
|
||||||
<span>restore backup ?</span>
|
<div class="text-center mb-3">
|
||||||
<ng-container>
|
<i class="fa-solid fa-rotate-left fa-3x text-warning mb-3"></i>
|
||||||
Are you sure that You want to <code style="padding: 0!important;">Restore this configuration</code> on
|
<h6>Restore Configuration Backup</h6>
|
||||||
device?<br />
|
</div>
|
||||||
<hr>
|
|
||||||
<p class="text-danger">
|
<div class="backup-info bg-light p-3 rounded mb-3">
|
||||||
All Current device configuration will be reset:<br /><br />
|
<h6 class="mb-2"><i class="fa-solid fa-info-circle me-2 text-primary"></i>Backup Details</h6>
|
||||||
* All state data/history on router will be reset<br />
|
<div class="row">
|
||||||
* All other local users on router will be deleted<br />
|
<div class="col-6"><strong>Device:</strong> {{currentBackup?.devname}}</div>
|
||||||
* After restore the password of the local user will be same as configured in MikroWizard<br />
|
<div class="col-6"><strong>IP:</strong> {{currentBackup?.devip}}</div>
|
||||||
</p>
|
<div class="col-6"><strong>Date:</strong> {{currentBackup?.createdC}}</div>
|
||||||
</ng-container>
|
<div class="col-6"><strong>Size:</strong> {{currentBackup?.filesize}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<c-alert color="danger" class="mb-0">
|
||||||
|
<h6 class="alert-heading"><i class="fa-solid fa-warning me-2"></i>Critical Warning</h6>
|
||||||
|
<p class="mb-2">This action will completely reset the device configuration:</p>
|
||||||
|
<ul class="mb-0">
|
||||||
|
<li>All current device configuration will be overwritten</li>
|
||||||
|
<li>All state data and history on router will be reset</li>
|
||||||
|
<li>All other local users on router will be deleted</li>
|
||||||
|
<li>Device will reboot and apply the restored configuration</li>
|
||||||
|
</ul>
|
||||||
|
</c-alert>
|
||||||
</c-modal-body>
|
</c-modal-body>
|
||||||
<c-modal-footer>
|
<c-modal-footer class="d-flex justify-content-between">
|
||||||
<button *ngIf="ispro" (click)="restore_backup(true)" cButton color="info">
|
<button cButton [cModalToggle]="ConfirmModal.id" color="secondary">
|
||||||
Restore this
|
<i class="fa-solid fa-times me-1"></i>Cancel
|
||||||
</button>
|
</button>
|
||||||
<button cButton [cModalToggle]="ConfirmModal.id" color="info">
|
<button *ngIf="ispro" (click)="restore_backup(true, false)" cButton color="warning">
|
||||||
Cancel
|
<i class="fa-solid fa-arrow-right me-1"></i>Continue to Final Confirmation
|
||||||
|
</button>
|
||||||
|
</c-modal-footer>
|
||||||
|
</c-modal>
|
||||||
|
|
||||||
|
<!-- Critical Double Confirmation -->
|
||||||
|
<c-modal #CriticalConfirmModal backdrop="static" [(visible)]="CriticalConfirmModalVisible" id="CriticalConfirmModal">
|
||||||
|
<c-modal-header class="bg-danger text-white">
|
||||||
|
<h5 cModalTitle><i class="fa-solid fa-skull-crossbones me-2"></i>CRITICAL: Final Confirmation Required</h5>
|
||||||
|
</c-modal-header>
|
||||||
|
<c-modal-body class="p-4">
|
||||||
|
<div class="text-center mb-4">
|
||||||
|
<i class="fa-solid fa-exclamation-triangle fa-4x text-danger mb-3"></i>
|
||||||
|
<h5 class="text-danger">DESTRUCTIVE ACTION</h5>
|
||||||
|
<p class="mb-0">You are about to permanently overwrite device configuration</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="confirmation-box bg-light border border-danger p-3 rounded">
|
||||||
|
<p class="mb-3 fw-bold">To proceed with this critical action, type <code>CONFIRM</code> in the box below:</p>
|
||||||
|
<input cFormControl [(ngModel)]="confirmationText" placeholder="Type CONFIRM to proceed"
|
||||||
|
class="form-control text-center fw-bold" style="letter-spacing: 2px;" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<c-alert color="info" class="mt-3 mb-0">
|
||||||
|
<small><i class="fa-solid fa-info-circle me-1"></i>
|
||||||
|
This confirmation ensures you understand the critical nature of this operation.
|
||||||
|
</small>
|
||||||
|
</c-alert>
|
||||||
|
</c-modal-body>
|
||||||
|
<c-modal-footer class="d-flex justify-content-between">
|
||||||
|
<button (click)="cancelCriticalRestore()" cButton color="secondary">
|
||||||
|
<i class="fa-solid fa-times me-1"></i>Cancel
|
||||||
|
</button>
|
||||||
|
<button (click)="restore_backup(true, true)" cButton color="danger"
|
||||||
|
[disabled]="confirmationText !== 'CONFIRM'">
|
||||||
|
<i class="fa-solid fa-rotate-left me-1"></i>RESTORE BACKUP
|
||||||
</button>
|
</button>
|
||||||
</c-modal-footer>
|
</c-modal-footer>
|
||||||
</c-modal>
|
</c-modal>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,72 @@
|
||||||
@import 'ngx-diff/styles/default-theme';
|
@import 'ngx-diff/styles/default-theme';
|
||||||
|
|
||||||
::ng-deep .modal-xl {
|
::ng-deep .modal-xl {
|
||||||
--cui-modal-width: 90vw!important;
|
--cui-modal-width: 90vw!important;
|
||||||
}
|
}
|
||||||
|
|
||||||
::ng-deep pre {
|
::ng-deep pre {
|
||||||
display: block!important;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -30,11 +30,13 @@ export class BackupsComponent implements OnInit {
|
||||||
public codeForHighlightAuto: string = "";
|
public codeForHighlightAuto: string = "";
|
||||||
public ispro: boolean = false;
|
public ispro: boolean = false;
|
||||||
public ConfirmModalVisible: boolean = false;
|
public ConfirmModalVisible: boolean = false;
|
||||||
|
public CriticalConfirmModalVisible: boolean = false;
|
||||||
public CompareModalVisible: boolean = false;
|
public CompareModalVisible: boolean = false;
|
||||||
public compareitems:any=[];
|
public compareitems:any=[];
|
||||||
public comparecontents:any=[];
|
public comparecontents:any=[];
|
||||||
public compare_type="unified";
|
public compare_type="unified";
|
||||||
public copy_msg:boolean=false;
|
public copy_msg:boolean=false;
|
||||||
|
public confirmationText: string = '';
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private data_provider: dataProvider,
|
private data_provider: dataProvider,
|
||||||
|
|
@ -186,31 +188,55 @@ export class BackupsComponent implements OnInit {
|
||||||
this.filters_visible = !this.filters_visible;
|
this.filters_visible = !this.filters_visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
restore_backup(apply:boolean=false){
|
restore_backup(apply: boolean = false, doubleConfirmed: boolean = false, backup?: any) {
|
||||||
var _slef=this;
|
var _self = this;
|
||||||
if (!apply){
|
|
||||||
|
// Set current backup if provided
|
||||||
|
if (backup) {
|
||||||
|
this.currentBackup = backup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!apply) {
|
||||||
|
// Step 1: Show initial confirmation
|
||||||
this.ConfirmModalVisible = true;
|
this.ConfirmModalVisible = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!this.currentBackup)
|
|
||||||
|
if (!this.currentBackup) {
|
||||||
return;
|
return;
|
||||||
if(apply){
|
}
|
||||||
_slef.ConfirmModalVisible = false;
|
|
||||||
_slef.BakcupModalVisible = true;
|
if (apply && !doubleConfirmed) {
|
||||||
this.show_toast('Success', 'Backup restored successfully', 'success')
|
// Step 2: Show critical confirmation
|
||||||
this.show_toast('Info', 'Wait for the router to reboot and apply config', 'info')
|
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) => {
|
this.data_provider.restore_backup(this.currentBackup.id).then((res) => {
|
||||||
if ('status' in res){
|
if ('status' in res) {
|
||||||
if(res['status']=='success'){
|
if (res['status'] == 'success') {
|
||||||
this.show_toast('Success', 'Backup restored successfully', 'success')
|
this.show_toast('Success', 'Backup restored successfully', 'success');
|
||||||
this.show_toast('Info', 'Wait for the router to reboot and apply config', 'info')
|
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(){
|
start_compare(){
|
||||||
var _self=this;
|
var _self=this;
|
||||||
|
|
@ -243,10 +269,20 @@ export class BackupsComponent implements OnInit {
|
||||||
this.compareitems.push(item);
|
this.compareitems.push(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete_compare(i:number){
|
delete_compare(i: number) {
|
||||||
//delete item index i from compareitems
|
// Delete item index i from compareitems
|
||||||
this.compareitems.splice(i,1);
|
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) {
|
reinitgrid(field: string, $event: any) {
|
||||||
if (field == "start") this.filters["start_time"] = $event.target.value;
|
if (field == "start") this.filters["start_time"] = $event.target.value;
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import {
|
||||||
ModalModule,
|
ModalModule,
|
||||||
FormModule,
|
FormModule,
|
||||||
ToastModule,
|
ToastModule,
|
||||||
|
AlertModule,
|
||||||
} from "@coreui/angular";
|
} from "@coreui/angular";
|
||||||
|
|
||||||
import { BackupsRoutingModule } from "./backups-routing.module";
|
import { BackupsRoutingModule } from "./backups-routing.module";
|
||||||
|
|
@ -34,10 +35,10 @@ import { ClipboardModule } from "@angular/cdk/clipboard";
|
||||||
FormModule,
|
FormModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
ButtonModule,
|
ButtonModule,
|
||||||
ButtonModule,
|
|
||||||
GuiGridModule,
|
GuiGridModule,
|
||||||
CollapseModule,
|
CollapseModule,
|
||||||
BadgeModule,
|
BadgeModule,
|
||||||
|
AlertModule,
|
||||||
Highlight,
|
Highlight,
|
||||||
HighlightAuto,
|
HighlightAuto,
|
||||||
HighlightLineNumbers,
|
HighlightLineNumbers,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue