Skip to content

Commit

Permalink
display bottom item in backup list and refactor for cleanliness (#1609)
Browse files Browse the repository at this point in the history
* display bottom item in backup list and refactor for cleanliness

* fix spelling mistake

* display initial toggle to deselect all, as all are selected by default

* add select/deselect all to backup restore and handle backup case when no services intalled

Co-authored-by: Lucy Cifferello <12953208+elvece@users.noreply.github.com>
  • Loading branch information
MattDHill and elvece committed Jul 4, 2022
1 parent 6d805ae commit 9319314
Show file tree
Hide file tree
Showing 11 changed files with 212 additions and 179 deletions.
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

0 comments on commit 9319314

Please sign in to comment.