react to enter key for alerts and modals. Styling and logic

This commit is contained in:
Matt Hill
2021-08-24 16:55:53 -06:00
committed by Matt Hill
parent 89229cdd1f
commit fc82fc2ec4
24 changed files with 195 additions and 229 deletions

View File

@@ -101,7 +101,7 @@
<ion-icon name="pulse"></ion-icon>
<ion-icon name="qr-code-outline"></ion-icon>
<ion-icon name="receipt-outline"></ion-icon>
<ion-icon name="refresh-outline"></ion-icon>
<ion-icon name="refresh"></ion-icon>
<ion-icon name="reload-outline"></ion-icon>
<ion-icon name="remove-outline"></ion-icon>
<ion-icon name="save-outline"></ion-icon>

View File

@@ -1,4 +1,4 @@
import { Component } from '@angular/core'
import { Component, HostListener } from '@angular/core'
import { Storage } from '@ionic/storage-angular'
import { AuthService, AuthState } from './services/auth.service'
import { ApiService } from './services/api/embassy-api.service'
@@ -24,6 +24,15 @@ import { Subscription } from 'rxjs'
styleUrls: ['app.component.scss'],
})
export class AppComponent {
@HostListener('document:keypress', ['$event'])
handleKeyboardEvent (event: KeyboardEvent) {
if (event.key === 'Enter') {
const elems = document.getElementsByClassName('enter-click')
const elem = elems[elems.length - 1] as HTMLButtonElement
if (elem) elem.click()
}
}
ServerStatus = ServerStatus
showMenu = false
selectedIndex = 0
@@ -143,6 +152,47 @@ export class AppComponent {
window.open(url, '_blank')
}
async presentAlertLogout () {
// @TODO warn user no way to recover Embassy if logout and forget password. Maybe require password to logout?
const alert = await this.alertCtrl.create({
header: 'Caution',
message: 'Are you sure you want to logout?',
buttons: [
{
text: 'Cancel',
role: 'cancel',
},
{
text: 'Logout',
cssClass: 'enter-click',
handler: () => {
this.logout()
},
},
],
})
await alert.present()
}
private async logout () {
const loader = await this.loadingCtrl.create({
spinner: 'lines',
message: 'Logging out...',
cssClass: 'loader',
})
await loader.present()
try {
await this.embassyApi.logout({ })
this.authService.setUnverified()
} catch (e) {
await this.errToast.present(e)
} finally {
loader.dismiss()
}
}
private watchConnection (): Subscription {
return this.connectionService.watchFailure$()
.pipe(
@@ -234,7 +284,7 @@ export class AppComponent {
})
}
async presentAlertRefreshNeeded () {
private async presentAlertRefreshNeeded () {
const alert = await this.alertCtrl.create({
backdropDismiss: false,
header: 'Refresh Needed',
@@ -242,6 +292,7 @@ export class AppComponent {
buttons: [
{
text: 'Refresh Page',
cssClass: 'enter-click',
handler: () => {
location.reload()
},
@@ -251,46 +302,6 @@ export class AppComponent {
await alert.present()
}
async presentAlertLogout () {
// @TODO warn user no way to recover Embassy if logout and forget password. Maybe require password to logout?
const alert = await this.alertCtrl.create({
backdropDismiss: false,
header: 'Caution',
message: 'Are you sure you want to logout?',
buttons: [
{
text: 'Cancel',
role: 'cancel',
},
{
text: 'Logout',
handler: () => {
this.logout()
},
},
],
})
await alert.present()
}
private async logout () {
const loader = await this.loadingCtrl.create({
spinner: 'lines',
message: 'Logging out...',
cssClass: 'loader',
})
await loader.present()
try {
await this.embassyApi.logout({ })
this.authService.setUnverified()
} catch (e) {
await this.errToast.present(e)
} finally {
loader.dismiss()
}
}
private async presentToastNotifications () {
const toast = await this.toastCtrl.create({
header: 'Embassy',

View File

@@ -1,15 +1,16 @@
<ion-item-group [formGroup]="formGroup">
<div *ngFor="let entry of formGroup.controls | keyvalue : asIsOrder">
<!-- union enum -->
<ng-container *ngIf="unionSpec && entry.key === unionSpec.tag.id">
<p class="input-label">{{ unionSpec.tag.name }}</p>
<ion-item>
<ion-label>{{ unionSpec.tag.name }}</ion-label>
<ion-select slot="end" placeholder="Select" [formControlName]="unionSpec.tag.id" [selectedText]="unionSpec.tag['variant-names'][entry.value.value]" (ionChange)="presentAlertChangeWarning(entry.key, unionSpec); updateUnion($event)">
<ion-select-option *ngFor="let option of Object.keys(unionSpec.variants)" [value]="option">
{{ unionSpec.tag['variant-names'][option] }}
</ion-select-option>
</ion-select>
</ion-item>
<p class="input-label">{{ unionSpec.tag.name }}</p>
<ion-item>
<ion-label>{{ unionSpec.tag.name }}</ion-label>
<ion-select [interfaceOptions]="{ message: getWarningText(unionSpec.warning) }" slot="end" placeholder="Select" [formControlName]="unionSpec.tag.id" [selectedText]="unionSpec.tag['variant-names'][entry.value.value]" (ionChange)="updateUnion($event)">
<ion-select-option *ngFor="let option of Object.keys(unionSpec.variants)" [value]="option">
{{ unionSpec.tag['variant-names'][option] }}
</ion-select-option>
</ion-select>
</ion-item>
</ng-container>
<ng-container *ngIf="objectSpec[entry.key] as spec">
<!-- primitive -->

View File

@@ -1,7 +1,7 @@
import { Component, Input, Output, SimpleChange, EventEmitter } from '@angular/core'
import { AbstractFormGroupDirective, FormArray, FormGroup } from '@angular/forms'
import { AlertController, IonicSafeString, ModalController } from '@ionic/angular'
import { ConfigSpec, ListValueSpecOf, ValueSpec, ValueSpecBoolean, ValueSpecList, ValueSpecListOf, ValueSpecNumber, ValueSpecString, ValueSpecUnion } from 'src/app/pkg-config/config-types'
import { AlertButton, AlertController, IonicSafeString, ModalController } from '@ionic/angular'
import { ConfigSpec, ListValueSpecOf, ValueSpec, ValueSpecBoolean, ValueSpecList, ValueSpecListOf, ValueSpecUnion } from 'src/app/pkg-config/config-types'
import { FormService } from 'src/app/services/form.service'
import { Range } from 'src/app/pkg-config/config-utilities'
import { EnumListPage } from 'src/app/modals/enum-list/enum-list.page'
@@ -34,17 +34,6 @@ export class FormObjectComponent {
) { }
ngOnChanges (changes: { [propName: string]: SimpleChange }) {
// @TODO figure out why changes are being triggered so often. If too heavy, switch to ngOnInit and figure out another way to manually reset defaults is executed. Needed because otherwise ObjectListInfo won't be accurate.
// if ( changes['current'] && changes['current'].previousValue != changes['current'].currentValue ) {
// console.log('CURRENT')
// }
// if ( changes['formGroup'] && changes['formGroup'].previousValue != changes['formGroup'].currentValue ) {
// console.log('FORM GROUP')
// }
// if ( changes['objectSpec'] && changes['objectSpec'].previousValue != changes['objectSpec'].currentValue ) {
// console.log('OBJECT SPEC')
// }
// Lists are automatically expanded, but their members are not
Object.keys(this.objectSpec).forEach(key => {
const spec = this.objectSpec[key]
@@ -157,12 +146,13 @@ export class FormObjectComponent {
if (!spec.warning || this.warningAck[key]) return okFn ? okFn() : null
this.warningAck[key] = true
const buttons = [
const buttons: AlertButton[] = [
{
text: 'Ok',
handler: () => {
if (okFn) okFn()
},
cssClass: 'enter-click',
},
]
@@ -186,7 +176,6 @@ export class FormObjectComponent {
async presentAlertDelete (key: string, index: number) {
const alert = await this.alertCtrl.create({
backdropDismiss: false,
header: 'Confirm',
message: 'Are you sure you want to delete this entry?',
buttons: [
@@ -199,6 +188,7 @@ export class FormObjectComponent {
handler: () => {
this.deleteListItem(key, index)
},
cssClass: 'enter-click',
},
],
})
@@ -260,7 +250,6 @@ export class FormLabelComponent {
const alert = await this.alertCtrl.create({
header: name,
message: description,
buttons: ['Ok'],
})
await alert.present()
}

View File

@@ -49,12 +49,12 @@
<!-- next/finish buttons -->
<ng-container *ngIf="!(currentSlide.loading$ | async)">
<!-- next -->
<ion-button slot="end" *ngIf="currentBottomBar.next as next" (click)="transitions.next()" fill="outline" class="toolbar-button" color="primary">
<ion-button slot="end" *ngIf="currentBottomBar.next as next" (click)="transitions.next()" fill="outline" class="toolbar-button enter-click">
<ion-text [class.smaller-text]="next.length > 16">{{ next }}</ion-text>
</ion-button>
<!-- finish -->
<ion-button slot="end" *ngIf="currentBottomBar.finish as finish" (click)="transitions.final()" fill="outline" class="toolbar-button" color="primary">
<ion-button slot="end" *ngIf="currentBottomBar.finish as finish" (click)="transitions.final()" fill="outline" class="toolbar-button enter-click">
<ion-text [class.smaller-text]="finish.length > 16">{{ finish }}</ion-text>
</ion-button>
</ng-container>

View File

@@ -1,9 +1,14 @@
<ion-header style="min-height: unset;">
<ion-toolbar *ngIf="patch.data['package-data'][pkgId] as pkg">
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-button (click)="dismiss()">
<ion-icon slot="icon-only" name="close"></ion-icon>
</ion-button>
</ion-buttons>
<ion-title>Config</ion-title>
<ion-buttons slot="end" class="ion-padding-end">
<ion-button fill="clear" [disabled]="loadingText" (click)="resetDefaults()">
<ion-icon slot="start" name="refresh-outline"></ion-icon>
<ion-icon slot="start" name="refresh"></ion-icon>
Reset Defaults
</ion-button>
</ion-buttons>
@@ -19,17 +24,11 @@
<ng-template #loaded>
<ng-container *ngIf="patch.data['package-data'][pkgId] as pkg">
<ng-container *ngIf="pkg.manifest.config && !pkg.installed.status.configured && !edited">
<ion-item class="notifier-item">
<ion-label>
<h2 style="display: flex; align-items: center; margin-bottom: 3px;">
<ion-icon size="small" style="margin-right: 5px" slot="start" color="dark" slot="start" name="alert-circle-outline"></ion-icon>
<ion-text style="font-size: smaller;">Initial Config</ion-text>
</h2>
<p style="font-size: small">To use the default config for {{ pkg.manifest.title }}, click "Save" above.</p>
</ion-label>
</ion-item>
</ng-container>
<ion-item>
<ion-label>
<ion-text color="success">To use the default config for {{ pkg.manifest.title }}, click "Save" below.</ion-text>
</ion-label>
</ion-item>
<ng-container *ngIf="rec && showRec">
<ion-item class="rec-item">
@@ -81,13 +80,8 @@
<ion-footer>
<ion-toolbar *ngIf="patch.data['package-data'][pkgId] as pkg">
<ion-buttons slot="start" class="ion-padding-start">
<ion-button fill="outline" (click)="dismiss()">
Cancel
</ion-button>
</ion-buttons>
<ion-buttons slot="end" class="ion-padding-end">
<ion-button fill="outline" color="primary" [disabled]="loadingText" (click)="save(pkg)">
<ion-button fill="outline" [disabled]="loadingText" (click)="save(pkg)" class="enter-click">
Save
</ion-button>
</ion-buttons>

View File

@@ -172,6 +172,7 @@ export class AppConfigPage {
handler: () => {
this.modalCtrl.dismiss()
},
cssClass: 'enter-click',
},
],
})

View File

@@ -1,10 +1,15 @@
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-button (click)="dismiss()">
<ion-icon slot="icon-only" name="close"></ion-icon>
</ion-button>
</ion-buttons>
<ion-title>
{{ spec.name }}
</ion-title>
<ion-buttons slot="end">
<ion-button slot="end" fill="clear" color="primary" (click)="toggleSelectAll()">
<ion-button slot="end" fill="clear" (click)="toggleSelectAll()">
{{ selectAll ? 'All' : 'None' }}
</ion-button>
</ion-buttons>
@@ -22,13 +27,8 @@
<ion-footer>
<ion-toolbar>
<ion-buttons slot="start" class="ion-padding-start">
<ion-button fill="outline" (click)="dismiss()">
Cancel
</ion-button>
</ion-buttons>
<ion-buttons slot="end" class="ion-padding-end">
<ion-button fill="outline" color="primary" (click)="save()">
<ion-button fill="outline" (click)="save()" class="enter-click">
Done
</ion-button>
</ion-buttons>

View File

@@ -1,5 +1,10 @@
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-button (click)="dismiss()">
<ion-icon slot="icon-only" name="close"></ion-icon>
</ion-button>
</ion-buttons>
<ion-title>{{ title }}</ion-title>
</ion-toolbar>
</ion-header>
@@ -15,13 +20,8 @@
<ion-footer>
<ion-toolbar>
<ion-buttons slot="start" class="ion-padding-start">
<ion-button fill="clear" (click)="dismiss()">
Cancel
</ion-button>
</ion-buttons>
<ion-buttons slot="end" class="ion-padding-end">
<ion-button *ngFor="let button of buttons" fill="clear" (click)="handleClick(button)">
<ion-button *ngFor="let button of buttons" fill="outline" (click)="handleClick(button)">
{{ button.text }}
</ion-button>
</ion-buttons>

View File

@@ -8,5 +8,5 @@
.main-content {
height: 100%;
color: var(--ion-color-medium);
color: var(--ion-color-dark);
}

View File

@@ -80,6 +80,7 @@ export class AppActionsPage {
handler: () => {
this.executeAction(pkg.manifest.id, action.key)
},
cssClass: 'enter-click',
},
],
})
@@ -104,7 +105,7 @@ export class AppActionsPage {
header: 'Forbidden',
message: error || `Action "${action.value.name}" can only be executed when service is ${statusesStr}`,
buttons: ['OK'],
cssClass: 'alert-error-message',
cssClass: 'alert-error-message enter-click',
})
await alert.present()
}
@@ -159,7 +160,13 @@ export class AppActionsPage {
const successAlert = await this.alertCtrl.create({
header: 'Execution Complete',
message: res.message.split('\n').join('</br ></br />'),
buttons: ['OK'],
buttons: [
{
text: 'Ok',
role: 'cancel',
cssClass: 'enter-click',
},
],
})
setTimeout(() => successAlert.present(), 400)

View File

@@ -6,7 +6,7 @@
<ion-title>Properties</ion-title>
<ion-buttons slot="end">
<ion-button (click)="refresh()">
<ion-icon slot="start" name="refresh-outline"></ion-icon>
<ion-icon slot="start" name="refresh"></ion-icon>
Refresh
</ion-button>
</ion-buttons>

View File

@@ -130,7 +130,6 @@ export class AppShowPage {
const alert = await this.alertCtrl.create({
header: 'Not Accepting Donations',
message: `The developers of ${this.pkg.manifest.title} have not provided a donation URL. Please contact them directly if you insist on giving them money.`,
buttons: ['OK'],
})
await alert.present()
}
@@ -215,6 +214,7 @@ export class AppShowPage {
handler: () => {
this.start()
},
cssClass: 'enter-click',
},
],
})

View File

@@ -140,18 +140,6 @@
<ion-row>
<ion-col sizeSm="12" sizeMd="6">
<ion-item-group>
<ion-item detail="false">
<ion-label>
<h2>Service ID</h2>
<p>{{ pkg.manifest.id }}</p>
</ion-label>
</ion-item>
<ion-item detail="false">
<ion-label>
<h2>Categories</h2>
<p>{{ pkg.categories.join(', ') }}</p>
</ion-label>
</ion-item>
<ion-item button detail="false" (click)="presentAlertVersions()">
<ion-label>
<h2>Other Versions</h2>
@@ -198,20 +186,6 @@
</ion-label>
<ion-icon slot="end" name="open-outline"></ion-icon>
</ion-item>
<ion-item [href]="pkg.manifest['marketing-site']" target="_blank" detail="false">
<ion-label>
<h2>Marketing Site</h2>
<p>{{ pkg.manifest['marketing-site'] }}</p>
</ion-label>
<ion-icon slot="end" name="open-outline"></ion-icon>
</ion-item>
<ion-item *ngIf="pkg.manifest['donation-url'] as donationUrl" [href]="donationUrl" target="_blank" detail="false">
<ion-label>
<h2>Donation Site</h2>
<p>{{ donationUrl }}</p>
</ion-label>
<ion-icon slot="end" name="open-outline"></ion-icon>
</ion-item>
</ion-item-group>
</ion-col>
</ion-row>

View File

@@ -81,7 +81,6 @@ export class MarketplaceShowPage {
async presentAlertVersions () {
const alert = await this.alertCtrl.create({
header: 'Versions',
backdropDismiss: false,
inputs: this.marketplaceService.pkgs[this.pkgId].versions.sort((a, b) => -1 * this.emver.compare(a, b)).map(v => {
return {
name: v, // for CSS
@@ -100,6 +99,7 @@ export class MarketplaceShowPage {
handler: (version: string) => {
this.getPkg(version)
},
cssClass: 'enter-click',
},
],
})

View File

@@ -32,7 +32,6 @@ export class SessionsPage {
async presentAlertKill (id: string) {
const alert = await this.alertCtrl.create({
backdropDismiss: false,
header: 'Caution',
message: `Are you sure you want to kill this session?`,
buttons: [
@@ -45,6 +44,7 @@ export class SessionsPage {
handler: () => {
this.kill(id)
},
cssClass: 'enter-click',
},
],
})

View File

@@ -22,7 +22,7 @@
<ion-item-divider>Saved Keys</ion-item-divider>
<ion-item button detail="false" (click)="serverConfig.presentModalInput('ssh')">
<ion-item button detail="false" (click)="presentModalAdd()">
<ion-icon slot="start" name="add" size="large"></ion-icon>
<ion-label>Add new key</ion-label>
</ion-item>

View File

@@ -1,10 +1,9 @@
import { Component } from '@angular/core'
import { ServerConfigService } from 'src/app/services/server-config.service'
import { AlertController, LoadingController } from '@ionic/angular'
import { SSHService } from './ssh.service'
import { Subscription } from 'rxjs'
import { AlertController, LoadingController, ModalController } from '@ionic/angular'
import { SSHKeys } from 'src/app/services/api/api.types'
import { ErrorToastService } from 'src/app/services/error-toast.service'
import { ApiService } from 'src/app/services/api/embassy-api.service'
import { BackupConfirmationComponent } from 'src/app/modals/backup-confirmation/backup-confirmation.component'
@Component({
selector: 'ssh-keys',
@@ -14,37 +13,66 @@ import { ErrorToastService } from 'src/app/services/error-toast.service'
export class SSHKeysPage {
loading = true
sshKeys: SSHKeys
subs: Subscription[] = []
readonly docsUrl = 'https://docs.start9.com/user-manual/general/developer-options/ssh-setup.html'
constructor (
private readonly loadingCtrl: LoadingController,
private readonly modalCtrl: ModalController,
private readonly errToast: ErrorToastService,
private readonly alertCtrl: AlertController,
private readonly sshService: SSHService,
public readonly serverConfig: ServerConfigService,
private readonly embassyApi: ApiService,
) { }
async ngOnInit () {
this.subs = [
this.sshService.watch$()
.subscribe(keys => {
this.sshKeys = keys
}),
]
await this.sshService.getKeys()
this.loading = false
await this.getKeys()
}
ngOnDestroy () {
this.subs.forEach(sub => sub.unsubscribe())
async getKeys (): Promise<void> {
try {
this.sshKeys = await this.embassyApi.getSshKeys({ })
} catch (e) {
this.errToast.present(e)
} finally {
this.loading = false
}
}
async presentModalAdd () {
const { name, description } = sshSpec
const modal = await this.modalCtrl.create({
component: BackupConfirmationComponent,
componentProps: {
title: name,
message: description,
label: name,
submitFn: this.add,
},
cssClass: 'alertlike-modal',
})
await modal.present()
}
async add (pubkey: string): Promise<void> {
const loader = await this.loadingCtrl.create({
spinner: 'lines',
message: 'Saving...',
cssClass: 'loader',
})
await loader.present()
try {
const key = await this.embassyApi.addSshKey({ pubkey })
this.sshKeys = { ...this.sshKeys, ...key }
} catch (e) {
this.errToast.present(e)
} finally {
loader.dismiss()
}
}
async presentAlertDelete (hash: string) {
const alert = await this.alertCtrl.create({
backdropDismiss: false,
header: 'Caution',
message: `Are you sure you want to delete this key?`,
buttons: [
@@ -57,6 +85,7 @@ export class SSHKeysPage {
handler: () => {
this.delete(hash)
},
cssClass: 'enter-click',
},
],
})
@@ -72,7 +101,8 @@ export class SSHKeysPage {
await loader.present()
try {
await this.sshService.delete(hash)
await this.embassyApi.deleteSshKey({ hash })
delete this.sshKeys[hash]
} catch (e) {
this.errToast.present(e)
} finally {
@@ -84,3 +114,15 @@ export class SSHKeysPage {
return 0
}
}
const sshSpec = {
type: 'string',
name: 'SSH Key',
description: 'Enter the SSH public key of you would like to authorize for root access to your Embassy.',
nullable: false,
// @TODO regex for SSH Key
// pattern: '',
'pattern-description': 'Must be a valid SSH key',
masked: false,
copyable: false,
}

View File

@@ -17,27 +17,5 @@ export class SSHService {
return this.keys$.asObservable()
}
async getKeys (): Promise<void> {
const keys = await this.embassyApi.getSshKeys({ })
this.keys$.next(keys)
}
async add (pubkey: string): Promise<void> {
const key = await this.embassyApi.addSshKey({ pubkey })
const keys = this.keys$.getValue()
this.keys$.next({ ...keys, ...key })
}
async delete (hash: string): Promise<void> {
await this.embassyApi.deleteSshKey({ hash })
const keys = this.keys$.getValue()
const filtered = Object.keys(keys)
.filter(h => h !== hash)
.reduce((res, h) => {
res[h] = keys[h]
return res
}, { })
this.keys$.next(filtered)
}
}

View File

@@ -27,7 +27,6 @@ export class ServerShowPage {
async presentAlertRestart () {
const alert = await this.alertCtrl.create({
backdropDismiss: false,
header: 'Confirm',
message: `Are you sure you want to restart your Embassy?`,
buttons: [
@@ -40,15 +39,15 @@ export class ServerShowPage {
handler: () => {
this.restart()
},
cssClass: 'enter-click',
},
]},
)
],
})
await alert.present()
}
async presentAlertShutdown () {
const alert = await this.alertCtrl.create({
backdropDismiss: false,
header: 'Confirm',
message: `Are you sure you want to shut down your Embassy? To turn it back on, you will need to physically unplug the device and plug it back in.`,
buttons: [
@@ -61,6 +60,7 @@ export class ServerShowPage {
handler: () => {
this.shutdown()
},
cssClass: 'enter-click',
},
],
})

View File

@@ -33,7 +33,7 @@ export class WifiPage {
try {
await this.getWifi()
} catch (e) {
this.errToast.present(e.message)
this.errToast.present(e)
} finally {
this.loading = false
}
@@ -72,7 +72,7 @@ export class WifiPage {
},
},
],
cssClass: 'wide-alert',
cssClass: 'wide-alert enter-click',
})
await alert.present()
}
@@ -206,7 +206,13 @@ export class WifiPage {
const alert = await this.alertCtrl.create({
header: `Connected to "${ssid}"`,
message: 'Note. It may take several minutes to an hour for your Embassy to reconnect over Tor.',
buttons: ['OK'],
buttons: [
{
text: 'Ok',
role: 'cancel',
cssClass: 'enter-click',
},
],
})
await alert.present()

View File

@@ -4,7 +4,6 @@ import { PatchConnection, PatchDbService } from './patch-db/patch-db.service'
import { HttpService, Method } from './http.service'
import { distinctUntilChanged } from 'rxjs/operators'
import { ConfigService } from './config.service'
import { pauseFor } from '../util/misc.util'
@Injectable({
providedIn: 'root',

View File

@@ -1,12 +1,9 @@
import { Injectable } from '@angular/core'
import { AlertInput, AlertButton } from '@ionic/core'
import { ApiService } from './api/embassy-api.service'
import { ConfigSpec, ValueSpecString } from '../pkg-config/config-types'
import { SSHService } from '../pages/server-routes/security-routes/ssh-keys/ssh.service'
import { ConfigSpec } from '../pkg-config/config-types'
import { AlertController, LoadingController } from '@ionic/angular'
import { ErrorToastService } from './error-toast.service'
import { ModalController } from '@ionic/angular'
import { BackupConfirmationComponent } from '../modals/backup-confirmation/backup-confirmation.component'
@Injectable({
providedIn: 'root',
@@ -14,12 +11,10 @@ import { BackupConfirmationComponent } from '../modals/backup-confirmation/backu
export class ServerConfigService {
constructor (
private readonly modalCtrl: ModalController,
private readonly loadingCtrl: LoadingController,
private readonly errToast: ErrorToastService,
private readonly alertCtrl: AlertController,
private readonly embassyApi: ApiService,
private readonly sshService: SSHService,
) { }
async presentAlert (key: string, current?: any): Promise<void> {
@@ -49,6 +44,7 @@ export class ServerConfigService {
loader.dismiss()
}
},
cssClass: 'enter-click',
},
]
@@ -84,24 +80,6 @@ export class ServerConfigService {
await alert.present()
}
async presentModalInput (key: string, current?: string) {
const { name, description, masked } = serverConfig[key] as ValueSpecString
const modal = await this.modalCtrl.create({
component: BackupConfirmationComponent,
componentProps: {
title: name,
message: description,
label: name,
useMask: masked,
value: current,
submitFn: this.saveFns[key],
},
cssClass: 'alertlike-modal',
})
await modal.present()
}
// async presentModalForm (key: string) {
// const modal = await this.modalCtrl.create({
// component: AppActionInputPage,
@@ -123,9 +101,6 @@ export class ServerConfigService {
'auto-check-updates': async (enabled: boolean) => {
return this.embassyApi.setDbValue({ pointer: '/auto-check-updates', value: enabled })
},
ssh: async (pubkey: string) => {
return this.sshService.add(pubkey)
},
// 'eos-marketplace': async () => {
// return this.embassyApi.setEosMarketplace()
// },
@@ -148,17 +123,6 @@ export const serverConfig: ConfigSpec = {
description: 'On launch, EmbassyOS will automatically check for updates of itself and your installed services. Updating still requires user approval and action. No updates will ever be performed automatically.',
default: true,
},
ssh: {
type: 'string',
name: 'SSH Key',
description: 'Enter the SSH public key of you would like to authorize for root access to your Embassy.',
nullable: false,
// @TODO regex for SSH Key
// pattern: '',
'pattern-description': 'Must be a valid SSH key',
masked: false,
copyable: false,
},
// 'eos-marketplace': {
// type: 'boolean',
// name: 'Tor Only Marketplace',

View File

@@ -155,7 +155,6 @@ export class StartupAlertsService {
private async displayAppsCheck (): Promise<boolean> {
return new Promise(async resolve => {
const alert = await this.alertCtrl.create({
backdropDismiss: true,
header: 'Updates Available!',
message: new IonicSafeString(
`<div style="display: flex; flex-direction: column; justify-content: space-around; min-height: 100px">
@@ -173,8 +172,9 @@ export class StartupAlertsService {
{
text: 'View in Marketplace',
handler: () => {
return this.navCtrl.navigateForward('/marketplace').then(() => resolve(false))
this.navCtrl.navigateForward('/marketplace').then(() => resolve(false))
},
cssClass: 'enter-click',
},
],
})
@@ -186,7 +186,6 @@ export class StartupAlertsService {
private async presentAlertNewOS (versionLatest: string): Promise<{ cancel?: true, update?: true }> {
return new Promise(async resolve => {
const alert = await this.alertCtrl.create({
backdropDismiss: true,
header: 'New EmbassyOS Version!',
message: new IonicSafeString(
`<div style="display: flex; flex-direction: column; justify-content: space-around; min-height: 100px">
@@ -204,6 +203,7 @@ export class StartupAlertsService {
{
text: 'Update',
handler: () => resolve({ update: true }),
cssClass: 'enter-click',
},
],
})