Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

display bottom item in backup list and refactor for cleanliness #1609

Merged
merged 4 commits into from
Jul 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
<ion-buttons slot="start">
<ion-back-button defaultHref="embassy"></ion-back-button>
</ion-buttons>
<ion-title>{{ title }}</ion-title>
<ion-title>{{
type === 'create' ? 'Create Backup' : 'Restore From Backup'
}}</ion-title>
<ion-buttons slot="end">
<ion-button [disabled]="backupService.loading" (click)="refresh()">
Refresh
<ion-icon slot="end" name="refresh"></ion-icon>
</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
</ion-header>
Original file line number Diff line number Diff line change
@@ -1,137 +1,145 @@
<!-- loading -->
<text-spinner
*ngIf="backupService.loading; else loaded"
[text]="loadingText"
></text-spinner>
<backup-drives-header [type]="type"></backup-drives-header>

<!-- loaded -->
<ng-template #loaded>
<!-- error -->
<ion-item *ngIf="backupService.loadingError; else noError">
<ion-label>
<ion-text color="danger">
{{ backupService.loadingError }}
</ion-text>
</ion-label>
</ion-item>
<ion-content class="ion-padding">
<!-- loading -->
<text-spinner
*ngIf="backupService.loading; else loaded"
[text]="loadingText"
></text-spinner>

<ng-template #noError>
<ion-item-group>
<!-- ** cifs ** -->
<ion-item-divider>LAN Shared Folders</ion-item-divider>
<ion-item>
<ion-label>
<h2>
LAN Shared Folders are the recommended way to create Embassy
backups. View the
<a
href="https://start9.com/latest/user-manual/backups/cifs-setup"
target="_blank"
noreferrer
>Instructions</a
>
</h2>
</ion-label>
</ion-item>
<!-- add new cifs -->
<ion-item button detail="false" (click)="presentModalAddCifs()">
<ion-icon
slot="start"
name="folder-open-outline"
size="large"
color="dark"
></ion-icon>
<ion-label>
<b>Open New</b>
</ion-label>
</ion-item>
<!-- cifs list -->
<ng-container *ngFor="let target of backupService.cifs; let i = index">
<ion-item button *ngIf="target.entry as cifs" (click)="select(target)">
<!-- loaded -->
<ng-template #loaded>
<!-- error -->
<ion-item *ngIf="backupService.loadingError; else noError">
<ion-label>
<ion-text color="danger">
{{ backupService.loadingError }}
</ion-text>
</ion-label>
</ion-item>

<ng-template #noError>
<ion-item-group>
<!-- ** cifs ** -->
<ion-item-divider>LAN Shared Folders</ion-item-divider>
<ion-item>
<ion-label>
<h2>
LAN Shared Folders are the recommended way to create Embassy
backups. View the
<a
href="https://start9.com/latest/user-manual/backups/cifs-setup"
target="_blank"
noreferrer
>Instructions</a
>
</h2>
</ion-label>
</ion-item>
<!-- add new cifs -->
<ion-item button detail="false" (click)="presentModalAddCifs()">
<ion-icon
slot="start"
name="folder-open-outline"
size="large"
color="dark"
></ion-icon>
<ion-label>
<h1>{{ cifs.path.split('/').pop() }}</h1>
<ng-container *ngIf="cifs.mountable">
<backup-drives-status
[type]="type"
[hasValidBackup]="target.hasValidBackup"
></backup-drives-status>
</ng-container>
<h2 *ngIf="!cifs.mountable" class="inline">
<ion-icon name="cellular-outline" color="danger"></ion-icon>
Unable to connect
</h2>
<p>Hostname: {{ cifs.hostname }}</p>
<p>Path: {{ cifs.path }}</p>
<b>Open New</b>
</ion-label>
<ion-note
slot="end"
class="click-area"
(click)="presentActionCifs($event, target, i)"
>
<ion-icon name="ellipsis-horizontal"></ion-icon>
</ion-note>
</ion-item>
</ng-container>
<!-- cifs list -->
<ng-container *ngFor="let target of backupService.cifs; let i = index">
<ion-item
button
*ngIf="target.entry as cifs"
(click)="select(target)"
>
<ion-icon
slot="start"
name="folder-open-outline"
size="large"
></ion-icon>
<ion-label>
<h1>{{ cifs.path.split('/').pop() }}</h1>
<ng-container *ngIf="cifs.mountable">
<backup-drives-status
[type]="type"
[hasValidBackup]="target.hasValidBackup"
></backup-drives-status>
</ng-container>
<h2 *ngIf="!cifs.mountable" class="inline">
<ion-icon name="cellular-outline" color="danger"></ion-icon>
Unable to connect
</h2>
<p>Hostname: {{ cifs.hostname }}</p>
<p>Path: {{ cifs.path }}</p>
</ion-label>
<ion-note
slot="end"
class="click-area"
(click)="presentActionCifs($event, target, i)"
>
<ion-icon name="ellipsis-horizontal"></ion-icon>
</ion-note>
</ion-item>
</ng-container>

<br />
<br />

<!-- ** drives ** -->
<ion-item-divider>Physical Drives</ion-item-divider>
<!-- no drives -->
<ion-item
*ngIf="!backupService.drives.length; else hasDrives"
class="ion-padding-bottom"
>
<ion-label>
<h2>
<ion-text color="warning">
Warning! Plugging a 2nd physical drive directly into your Embassy
can lead to data corruption.
</ion-text>
To safely create a backup to a physical drive, view the
<a
href="https://start9.com/latest/user-manual/backups/backups-create/#backup-using-a-physical-drive"
target="_blank"
noreferrer
>instructions</a
>.
</h2>
<br />
<h2>
If your drive is plugged in and does not appear, try
<a (click)="refresh()" style="cursor: pointer">refreshing</a>.
</h2>
</ion-label>
</ion-item>
<!-- drives detected -->
<ng-template #hasDrives>
<!-- ** drives ** -->
<ion-item-divider>Physical Drives</ion-item-divider>
<!-- no drives -->
<ion-item
button
*ngFor="let target of backupService.drives"
(click)="select(target)"
*ngIf="!backupService.drives.length; else hasDrives"
class="ion-padding-bottom"
>
<ion-icon slot="start" name="save-outline" size="large"></ion-icon>
<ng-container *ngIf="target.entry as drive">
<ion-label>
<h1>{{ drive.label || drive.logicalname }}</h1>
<backup-drives-status
[type]="type"
[hasValidBackup]="target.hasValidBackup"
></backup-drives-status>
<p>
{{ drive.vendor || 'Unknown Vendor' }} -
{{ drive.model || 'Unknown Model' }}
</p>
<p>Capacity: {{ drive.capacity | convertBytes }}</p>
</ion-label>
</ng-container>
<ion-label>
<h2>
<ion-text color="warning">
Warning! Plugging a 2nd physical drive directly into your
Embassy can lead to data corruption.
</ion-text>
To safely create a backup to a physical drive, view the
<a
href="https://start9.com/latest/user-manual/backups/backups-create/#backup-using-a-physical-drive"
target="_blank"
noreferrer
>instructions</a
>.
</h2>
<br />
<h2>
If your drive is plugged in and does not appear, try
<a (click)="refresh()" style="cursor: pointer">refreshing</a>.
</h2>
</ion-label>
</ion-item>
</ng-template>
</ion-item-group>
<!-- drives detected -->
<ng-template #hasDrives>
<ion-item
button
*ngFor="let target of backupService.drives"
(click)="select(target)"
>
<ion-icon slot="start" name="save-outline" size="large"></ion-icon>
<ng-container *ngIf="target.entry as drive">
<ion-label>
<h1>{{ drive.label || drive.logicalname }}</h1>
<backup-drives-status
[type]="type"
[hasValidBackup]="target.hasValidBackup"
></backup-drives-status>
<p>
{{ drive.vendor || 'Unknown Vendor' }} -
{{ drive.model || 'Unknown Model' }}
</p>
<p>Capacity: {{ drive.capacity | convertBytes }}</p>
</ion-label>
</ng-container>
</ion-item>
</ng-template>
</ion-item-group>
</ng-template>
</ng-template>
</ng-template>
</ion-content>
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@ import { ApiService } from 'src/app/services/api/embassy-api.service'
import { ErrorToastService } from '@start9labs/shared'
import { MappedBackupTarget } from 'src/app/types/mapped-backup-target'

type BackupType = 'create' | 'restore'

@Component({
selector: 'backup-drives',
templateUrl: './backup-drives.component.html',
styleUrls: ['./backup-drives.component.scss'],
})
export class BackupDrivesComponent {
@Input() type: 'create' | 'restore'
@Input() type: BackupType
@Output() onSelect: EventEmitter<
MappedBackupTarget<CifsBackupTarget | DiskBackupTarget>
> = new EventEmitter()
Expand Down Expand Up @@ -232,7 +234,7 @@ export class BackupDrivesComponent {
styleUrls: ['./backup-drives.component.scss'],
})
export class BackupDrivesHeaderComponent {
@Input() title: string
@Input() type: BackupType
@Output() onClose: EventEmitter<void> = new EventEmitter()

constructor(public readonly backupService: BackupService) {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@

<ion-content>
<ion-item-group>
<ion-item-divider>
<ion-buttons slot="end" style="padding-bottom: 6px">
<ion-button fill="clear" (click)="toggleSelectAll()">
<b>{{ selectAll ? 'Select All' : 'Deselect All' }}</b>
</ion-button>
</ion-buttons>
</ion-item-divider>
<ion-item *ngFor="let option of options">
<ion-label>
<h2>{{ option.title }}</h2>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export class AppRecoverSelectPage {
'newer-eos': boolean
})[]
hasSelection = false
selectAll = true
error: string | IonicSafeString

constructor(
Expand Down Expand Up @@ -62,6 +63,11 @@ export class AppRecoverSelectPage {
this.hasSelection = this.options.some(o => o.checked)
}

toggleSelectAll() {
this.options.forEach(pkg => (pkg.checked = this.selectAll))
this.selectAll = !this.selectAll
}

async restore(): Promise<void> {
const ids = this.options
.filter(option => !!option.checked)
Expand Down
Loading