changes in css
This commit is contained in:
@@ -15,7 +15,7 @@
|
||||
<div class="operations-center">
|
||||
<div class="operations-center__actions">
|
||||
<button pButton type="button" icon="pi pi-upload" [label]="'dashboard.exportAll' | translate" [loading]="exporting" (click)="exportAll()"></button>
|
||||
<button pButton type="button" severity="secondary" styleClass="btn-binary-accent" icon="pi pi-database" [label]="'dashboard.binaryAll' | translate" [loading]="runningBinary" (click)="binaryAll()"></button>
|
||||
<button pButton type="button" icon="pi pi-database" [label]="'dashboard.binaryAll' | translate" [loading]="runningBinary" (click)="binaryAll()"></button>
|
||||
</div>
|
||||
|
||||
<div class="operations-center__stats">
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
<div header-actions class="header-actions-row router-header-actions router-header-actions--desktop">
|
||||
<button pButton type="button" severity="secondary" icon="pi pi-pencil" [label]="'common.edit' | translate" (click)="openEdit()"></button>
|
||||
<button *ngIf="!isSwitchos" pButton type="button" icon="pi pi-upload" [label]="'routers.exportOne' | translate" [loading]="exporting" [disabled]="routerItem?.disable_all_backups || routerItem?.disable_export_backups" (click)="runExport()"></button>
|
||||
<button pButton type="button" severity="secondary" icon="pi pi-database" [label]="(isSwitchos ? 'routers.downloadSwitchBackup' : 'routers.binaryOne') | translate" [loading]="runningBinary" [disabled]="routerItem?.disable_all_backups || routerItem?.disable_binary_backups" (click)="runBinary()"></button>
|
||||
<button pButton type="button" severity="info" icon="pi pi-wifi" [label]="'routers.testConnection' | translate" [loading]="testing" (click)="testConnection()"></button>
|
||||
<button pButton type="button" severity="info" icon="pi pi-database" [label]="(isSwitchos ? 'routers.downloadSwitchBackup' : 'routers.binaryOne') | translate" [loading]="runningBinary" [disabled]="routerItem?.disable_all_backups || routerItem?.disable_binary_backups" (click)="runBinary()"></button>
|
||||
<button pButton type="button" severity="secondary" icon="pi pi-wifi" [label]="'routers.testConnection' | translate" [loading]="testing" (click)="testConnection()"></button>
|
||||
<button pButton type="button" severity="danger" icon="pi pi-trash" [label]="'routers.deleteDevice' | translate" [loading]="deletingRouter" (click)="deleteRouter()"></button>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
<app-page-header [eyebrow]="'switchosBeta.eyebrow' | translate" [title]="'switchosBeta.title' | translate" [subtitle]="'switchosBeta.subtitle' | translate">
|
||||
<div header-actions class="header-actions-row">
|
||||
<p-tag severity="warn" [value]="'switchosBeta.betaTag' | translate"></p-tag>
|
||||
</div>
|
||||
</app-page-header>
|
||||
|
||||
<app-section-card [title]="'switchosBeta.warningTitle' | translate" [subtitle]="'switchosBeta.warningSubtitle' | translate">
|
||||
<div class="beta-banner">
|
||||
<div>
|
||||
<strong>{{ 'switchosBeta.warningHeadline' | translate }}</strong>
|
||||
<p>{{ 'switchosBeta.warningBody' | translate }}</p>
|
||||
</div>
|
||||
<p-tag severity="warn" [value]="'switchosBeta.betaTag' | translate"></p-tag>
|
||||
</div>
|
||||
</app-section-card>
|
||||
|
||||
<div class="metric-grid-2 swos-beta-grid">
|
||||
<app-section-card [title]="'switchosBeta.formTitle' | translate" [subtitle]="'switchosBeta.formSubtitle' | translate">
|
||||
<form [formGroup]="form" class="form-grid-2">
|
||||
<span class="form-field">
|
||||
<label>{{ 'switchosBeta.label' | translate }}</label>
|
||||
<input pInputText formControlName="label" [placeholder]="'switchosBeta.labelPlaceholder' | translate" />
|
||||
</span>
|
||||
<span class="form-field">
|
||||
<label>{{ 'switchosBeta.host' | translate }}</label>
|
||||
<input pInputText formControlName="host" [placeholder]="'switchosBeta.hostPlaceholder' | translate" />
|
||||
</span>
|
||||
<span class="form-field">
|
||||
<label>{{ 'switchosBeta.port' | translate }}</label>
|
||||
<input pInputText type="number" formControlName="port" placeholder="80" />
|
||||
</span>
|
||||
<span class="form-field">
|
||||
<label>{{ 'switchosBeta.username' | translate }}</label>
|
||||
<input pInputText formControlName="username" placeholder="admin" />
|
||||
</span>
|
||||
<span class="form-field form-field--full">
|
||||
<label>{{ 'switchosBeta.password' | translate }}</label>
|
||||
<input pInputText type="password" formControlName="password" [placeholder]="'switchosBeta.passwordPlaceholder' | translate" />
|
||||
</span>
|
||||
<div class="dialog-actions swos-beta-actions">
|
||||
<button pButton type="button" severity="secondary" icon="pi pi-search" [label]="'switchosBeta.probeButton' | translate" [loading]="probing" (click)="probe()"></button>
|
||||
<button pButton type="button" icon="pi pi-download" [label]="'switchosBeta.downloadButton' | translate" [loading]="downloading" (click)="download()"></button>
|
||||
</div>
|
||||
</form>
|
||||
</app-section-card>
|
||||
|
||||
<app-section-card [title]="'switchosBeta.resultTitle' | translate" [subtitle]="'switchosBeta.resultSubtitle' | translate">
|
||||
<div class="empty-state" *ngIf="!probeResult && !lastError">{{ 'switchosBeta.resultEmpty' | translate }}</div>
|
||||
|
||||
<div class="swos-beta-result" *ngIf="probeResult">
|
||||
<div class="swos-beta-result__item">
|
||||
<span>{{ 'switchosBeta.baseUrl' | translate }}</span>
|
||||
<strong>{{ probeResult.base_url }}</strong>
|
||||
</div>
|
||||
<div class="swos-beta-result__item">
|
||||
<span>{{ 'switchosBeta.httpStatus' | translate }}</span>
|
||||
<strong>{{ probeResult.status_code }}</strong>
|
||||
</div>
|
||||
<div class="swos-beta-result__item">
|
||||
<span>{{ 'switchosBeta.authMode' | translate }}</span>
|
||||
<strong>{{ probeResult.auth_mode }}</strong>
|
||||
</div>
|
||||
<div class="swos-beta-result__item">
|
||||
<span>{{ 'switchosBeta.pageTitle' | translate }}</span>
|
||||
<strong>{{ probeResult.page_title || '—' }}</strong>
|
||||
</div>
|
||||
<div class="swos-beta-result__item">
|
||||
<span>{{ 'switchosBeta.serverHeader' | translate }}</span>
|
||||
<strong>{{ probeResult.server || '—' }}</strong>
|
||||
</div>
|
||||
<div class="swos-beta-result__item">
|
||||
<span>{{ 'switchosBeta.backupEndpoint' | translate }}</span>
|
||||
<strong>{{ (probeResult.backup_endpoint_ok ? 'switchosBeta.available' : 'switchosBeta.unavailable') | translate }}</strong>
|
||||
</div>
|
||||
<div class="swos-beta-note" *ngIf="probeResult.note">{{ probeResult.note }}</div>
|
||||
</div>
|
||||
|
||||
<div class="beta-error" *ngIf="lastError">{{ lastError }}</div>
|
||||
</app-section-card>
|
||||
</div>
|
||||
@@ -1,131 +0,0 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { HttpErrorResponse, HttpResponse } from '@angular/common/http';
|
||||
import { Component, inject } from '@angular/core';
|
||||
import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { finalize } from 'rxjs';
|
||||
import { ButtonModule } from 'primeng/button';
|
||||
import { InputTextModule } from 'primeng/inputtext';
|
||||
import { TagModule } from 'primeng/tag';
|
||||
|
||||
import { ApiService } from '../../core/services/api.service';
|
||||
import { UiService } from '../../core/services/ui.service';
|
||||
import { PageHeaderComponent } from '../../shared/ui/page-header.component';
|
||||
import { SectionCardComponent } from '../../shared/ui/section-card.component';
|
||||
|
||||
interface SwosBetaProbeResult {
|
||||
success: boolean;
|
||||
base_url: string;
|
||||
status_code: number;
|
||||
auth_mode: string;
|
||||
page_title?: string | null;
|
||||
content_type?: string | null;
|
||||
server?: string | null;
|
||||
save_backup_visible: boolean;
|
||||
backup_endpoint_ok: boolean;
|
||||
note?: string | null;
|
||||
}
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
imports: [CommonModule, ReactiveFormsModule, TranslateModule, ButtonModule, InputTextModule, TagModule, PageHeaderComponent, SectionCardComponent],
|
||||
templateUrl: './swos-beta-page.component.html'
|
||||
})
|
||||
export class SwosBetaPageComponent {
|
||||
private readonly api = inject(ApiService);
|
||||
private readonly fb = inject(FormBuilder);
|
||||
private readonly ui = inject(UiService);
|
||||
|
||||
probing = false;
|
||||
downloading = false;
|
||||
lastError = '';
|
||||
probeResult?: SwosBetaProbeResult;
|
||||
|
||||
readonly form = this.fb.nonNullable.group({
|
||||
label: '',
|
||||
host: ['', Validators.required],
|
||||
port: [80, [Validators.required, Validators.min(1), Validators.max(65535)]],
|
||||
username: ['admin', Validators.required],
|
||||
password: ''
|
||||
});
|
||||
|
||||
get formValue() {
|
||||
return this.form.getRawValue();
|
||||
}
|
||||
|
||||
probe() {
|
||||
if (this.form.invalid || this.probing) {
|
||||
this.form.markAllAsTouched();
|
||||
return;
|
||||
}
|
||||
|
||||
this.lastError = '';
|
||||
this.probing = true;
|
||||
this.api.http
|
||||
.post<SwosBetaProbeResult>(`${this.api.baseUrl}/swos-beta/probe`, this.formValue)
|
||||
.pipe(finalize(() => (this.probing = false)))
|
||||
.subscribe({
|
||||
next: (result) => {
|
||||
this.probeResult = result;
|
||||
this.ui.success('toast.swosBetaProbeOk');
|
||||
},
|
||||
error: (error: HttpErrorResponse) => {
|
||||
this.probeResult = undefined;
|
||||
this.lastError = this.extractError(error);
|
||||
this.ui.error('toast.swosBetaProbeFailed');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
download() {
|
||||
if (this.form.invalid || this.downloading) {
|
||||
this.form.markAllAsTouched();
|
||||
return;
|
||||
}
|
||||
|
||||
this.lastError = '';
|
||||
this.downloading = true;
|
||||
this.api.http
|
||||
.post(`${this.api.baseUrl}/swos-beta/download`, this.formValue, {
|
||||
observe: 'response',
|
||||
responseType: 'blob'
|
||||
})
|
||||
.pipe(finalize(() => (this.downloading = false)))
|
||||
.subscribe({
|
||||
next: (response) => {
|
||||
this.saveBlob(response);
|
||||
this.ui.success('toast.swosBetaDownloadOk');
|
||||
},
|
||||
error: (error: HttpErrorResponse) => {
|
||||
this.lastError = this.extractError(error);
|
||||
this.ui.error('toast.swosBetaDownloadFailed');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private saveBlob(response: HttpResponse<Blob>) {
|
||||
const blob = response.body || new Blob();
|
||||
const url = URL.createObjectURL(blob);
|
||||
const link = document.createElement('a');
|
||||
link.href = url;
|
||||
link.download = this.extractFilename(response.headers.get('content-disposition'));
|
||||
link.click();
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
|
||||
private extractFilename(disposition: string | null): string {
|
||||
const match = disposition?.match(/filename="?([^\"]+)"?/i);
|
||||
return match?.[1] || 'switchos-backup.swb';
|
||||
}
|
||||
|
||||
private extractError(error: HttpErrorResponse): string {
|
||||
const detail = error.error?.detail;
|
||||
if (typeof detail === 'string' && detail.trim()) {
|
||||
return detail.trim();
|
||||
}
|
||||
if (typeof error.error === 'string' && error.error.trim()) {
|
||||
return error.error.trim();
|
||||
}
|
||||
return this.ui.instant('switchosBeta.genericError');
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
<div class="sidebar-brand">
|
||||
<div class="sidebar-brand__logo">
|
||||
<img src="https://mikrotik.com/logo/library/logo/SVG/MT_Symbol_Black.svg" alt="MikroTik" />
|
||||
<img src="assets/mikrotik-w4y9rth430h5bcfzp9in8i.webp" alt="MikroTik" />
|
||||
</div>
|
||||
<div class="sidebar-brand__text" *ngIf="!collapsed">
|
||||
<h2>{{ 'sidebar.title' | translate }}</h2>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
},
|
||||
"sidebar": {
|
||||
"title": "Mikrotik Backup System",
|
||||
"subtitle": "Device backup platform"
|
||||
"subtitle": "RouterOS/SwitchOS"
|
||||
},
|
||||
"topbar": {
|
||||
"caption": "mikrotik / control center",
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
},
|
||||
"sidebar": {
|
||||
"title": "copia de MikroTik",
|
||||
"subtitle": "gestor de RouterOS/SwitchOS"
|
||||
"subtitle": "RouterOS/SwitchOS"
|
||||
},
|
||||
"topbar": {
|
||||
"caption": "mikrotik / centro de control",
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
},
|
||||
"sidebar": {
|
||||
"title": "MikroTik-backup",
|
||||
"subtitle": "RouterOS/SwitchOS-behandler"
|
||||
},
|
||||
"subtitle": "RouterOS/SwitchOS" },
|
||||
"topbar": {
|
||||
"caption": "mikrotik / kontrollsenter",
|
||||
"role": "administrator",
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
},
|
||||
"sidebar": {
|
||||
"title": "Mikrotik Backup System",
|
||||
"subtitle": "Device backup platform"
|
||||
"subtitle": "RouterOS/SwitchOS"
|
||||
},
|
||||
"topbar": {
|
||||
"caption": "mikrotik / control center",
|
||||
@@ -182,7 +182,7 @@
|
||||
"binaryLabel": "Backupy binarne",
|
||||
"binaryLabelHint": "Obrazy odzyskiwania",
|
||||
"connectionLabel": "Połączenie",
|
||||
"connectionLabelHint": "Status automatycznego lub ręcznego testu połączenia",
|
||||
"connectionLabelHint": "Status testu połączenia",
|
||||
"probeTag": "Test",
|
||||
"accessTag": "Dostęp",
|
||||
"sshUserHint": "Efektywny login urządzenia",
|
||||
|
||||
BIN
frontend/src/assets/mikrotik-w4y9rth430h5bcfzp9in8i.webp
Normal file
BIN
frontend/src/assets/mikrotik-w4y9rth430h5bcfzp9in8i.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.7 KiB |
@@ -1048,6 +1048,7 @@ body.dark-theme .topbar {
|
||||
padding: 0.55rem;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
place-items: center;
|
||||
box-shadow: inset 0 0 0 1px rgba(17, 20, 23, 0.08);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user