mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-31 04:23:40 +00:00
Feature/shared refactor (#1176)
* refactor: move most of the shared entities to @start8labs/shared library
This commit is contained in:
@@ -4,7 +4,7 @@ import { Routes, RouterModule } from '@angular/router'
|
||||
import { IonicModule } from '@ionic/angular'
|
||||
import { AppActionsPage, AppActionsItemComponent } from './app-actions.page'
|
||||
import { QRComponentModule } from 'src/app/components/qr/qr.component.module'
|
||||
import { SharingModule } from 'src/app/modules/sharing.module'
|
||||
import { SharedPipesModule } from '@start9labs/shared'
|
||||
import { GenericFormPageModule } from 'src/app/modals/generic-form/generic-form.module'
|
||||
import { ActionSuccessPageModule } from 'src/app/modals/action-success/action-success.module'
|
||||
|
||||
@@ -21,13 +21,10 @@ const routes: Routes = [
|
||||
IonicModule,
|
||||
RouterModule.forChild(routes),
|
||||
QRComponentModule,
|
||||
SharingModule,
|
||||
SharedPipesModule,
|
||||
GenericFormPageModule,
|
||||
ActionSuccessPageModule,
|
||||
],
|
||||
declarations: [
|
||||
AppActionsPage,
|
||||
AppActionsItemComponent,
|
||||
],
|
||||
declarations: [AppActionsPage, AppActionsItemComponent],
|
||||
})
|
||||
export class AppActionsPageModule { }
|
||||
export class AppActionsPageModule {}
|
||||
|
||||
@@ -19,7 +19,7 @@ import { WizardBaker } from 'src/app/components/install-wizard/prebaked-wizards'
|
||||
import { Subscription } from 'rxjs'
|
||||
import { GenericFormPage } from 'src/app/modals/generic-form/generic-form.page'
|
||||
import { ErrorToastService } from 'src/app/services/error-toast.service'
|
||||
import { isEmptyObject } from 'src/app/util/misc.util'
|
||||
import { isEmptyObject } from '@start9labs/shared'
|
||||
import { ActionSuccessPage } from 'src/app/modals/action-success/action-success.page'
|
||||
|
||||
@Component({
|
||||
|
||||
@@ -2,8 +2,11 @@ import { NgModule } from '@angular/core'
|
||||
import { CommonModule } from '@angular/common'
|
||||
import { Routes, RouterModule } from '@angular/router'
|
||||
import { IonicModule } from '@ionic/angular'
|
||||
import { AppInterfacesItemComponent, AppInterfacesPage } from './app-interfaces.page'
|
||||
import { SharingModule } from 'src/app/modules/sharing.module'
|
||||
import {
|
||||
AppInterfacesItemComponent,
|
||||
AppInterfacesPage,
|
||||
} from './app-interfaces.page'
|
||||
import { SharedPipesModule } from '@start9labs/shared'
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
@@ -17,11 +20,8 @@ const routes: Routes = [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
RouterModule.forChild(routes),
|
||||
SharingModule,
|
||||
],
|
||||
declarations: [
|
||||
AppInterfacesPage,
|
||||
AppInterfacesItemComponent,
|
||||
SharedPipesModule,
|
||||
],
|
||||
declarations: [AppInterfacesPage, AppInterfacesItemComponent],
|
||||
})
|
||||
export class AppInterfacesPageModule { }
|
||||
export class AppInterfacesPageModule {}
|
||||
|
||||
@@ -2,7 +2,10 @@ import { Component, Input, ViewChild } from '@angular/core'
|
||||
import { ActivatedRoute } from '@angular/router'
|
||||
import { IonContent, ToastController } from '@ionic/angular'
|
||||
import { getUiInterfaceKey } from 'src/app/services/config.service'
|
||||
import { InstalledPackageDataEntry, InterfaceDef } from 'src/app/services/patch-db/data-model'
|
||||
import {
|
||||
InstalledPackageDataEntry,
|
||||
InterfaceDef,
|
||||
} from 'src/app/services/patch-db/data-model'
|
||||
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
||||
import { copyToClipboard } from 'src/app/util/web.util'
|
||||
|
||||
@@ -22,12 +25,12 @@ export class AppInterfacesPage {
|
||||
other: LocalInterface[] = []
|
||||
pkgId: string
|
||||
|
||||
constructor (
|
||||
constructor(
|
||||
private readonly route: ActivatedRoute,
|
||||
public readonly patch: PatchDbService,
|
||||
) { }
|
||||
) {}
|
||||
|
||||
ngOnInit () {
|
||||
ngOnInit() {
|
||||
this.pkgId = this.route.snapshot.paramMap.get('pkgId')
|
||||
const pkg = this.patch.getData()['package-data'][this.pkgId]
|
||||
const interfaces = pkg.manifest.interfaces
|
||||
@@ -40,8 +43,12 @@ export class AppInterfacesPage {
|
||||
this.ui = {
|
||||
def: interfaces[uiKey],
|
||||
addresses: {
|
||||
'lan-address': uiAddresses['lan-address'] ? 'https://' + uiAddresses['lan-address'] : null,
|
||||
'tor-address': uiAddresses['tor-address'] ? 'http://' + uiAddresses['tor-address'] : null,
|
||||
'lan-address': uiAddresses['lan-address']
|
||||
? 'https://' + uiAddresses['lan-address']
|
||||
: null,
|
||||
'tor-address': uiAddresses['tor-address']
|
||||
? 'http://' + uiAddresses['tor-address']
|
||||
: null,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -53,18 +60,22 @@ export class AppInterfacesPage {
|
||||
return {
|
||||
def: interfaces[key],
|
||||
addresses: {
|
||||
'lan-address': addresses['lan-address'] ? 'https://' + addresses['lan-address'] : null,
|
||||
'tor-address': addresses['tor-address'] ? 'http://' + addresses['tor-address'] : null,
|
||||
'lan-address': addresses['lan-address']
|
||||
? 'https://' + addresses['lan-address']
|
||||
: null,
|
||||
'tor-address': addresses['tor-address']
|
||||
? 'http://' + addresses['tor-address']
|
||||
: null,
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
ngAfterViewInit () {
|
||||
ngAfterViewInit() {
|
||||
this.content.scrollToPoint(undefined, 1)
|
||||
}
|
||||
|
||||
asIsOrder () {
|
||||
asIsOrder() {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
@@ -77,18 +88,17 @@ export class AppInterfacesPage {
|
||||
export class AppInterfacesItemComponent {
|
||||
@Input() interface: LocalInterface
|
||||
|
||||
constructor (
|
||||
private readonly toastCtrl: ToastController,
|
||||
) { }
|
||||
constructor(private readonly toastCtrl: ToastController) {}
|
||||
|
||||
launch (url: string): void {
|
||||
launch(url: string): void {
|
||||
window.open(url, '_blank', 'noreferrer')
|
||||
}
|
||||
|
||||
async copy (address: string): Promise<void> {
|
||||
async copy(address: string): Promise<void> {
|
||||
let message = ''
|
||||
await copyToClipboard(address || '')
|
||||
.then(success => { message = success ? 'copied to clipboard!' : 'failed to copy' })
|
||||
await copyToClipboard(address || '').then(success => {
|
||||
message = success ? 'copied to clipboard!' : 'failed to copy'
|
||||
})
|
||||
|
||||
const toast = await this.toastCtrl.create({
|
||||
header: message,
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
Inject,
|
||||
Input,
|
||||
} from '@angular/core'
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
|
||||
import {
|
||||
PackageMainStatus,
|
||||
PackageDataEntry,
|
||||
Manifest,
|
||||
} from 'src/app/services/patch-db/data-model'
|
||||
import { PkgInfo } from 'src/app/util/get-package-info'
|
||||
|
||||
@@ -34,16 +34,16 @@ export class AppListReorderComponent {
|
||||
|
||||
readonly connectionFailure$ = this.connectionService
|
||||
.watchFailure$()
|
||||
.pipe(map((failure) => failure !== ConnectionFailure.None))
|
||||
.pipe(map(failure => failure !== ConnectionFailure.None))
|
||||
|
||||
constructor (private readonly connectionService: ConnectionService) { }
|
||||
constructor(private readonly connectionService: ConnectionService) {}
|
||||
|
||||
toggle () {
|
||||
toggle() {
|
||||
this.reordering = !this.reordering
|
||||
this.reorderingChange.emit(this.reordering)
|
||||
}
|
||||
|
||||
reorder ({ detail }: CustomEvent<ItemReorderEventDetail>): void {
|
||||
reorder({ detail }: CustomEvent<ItemReorderEventDetail>): void {
|
||||
this.pkgs = detail.complete([...this.pkgs])
|
||||
this.pkgsChange.emit(this.pkgs)
|
||||
}
|
||||
|
||||
@@ -3,9 +3,14 @@ import { CommonModule } from '@angular/common'
|
||||
import { Routes, RouterModule } from '@angular/router'
|
||||
import { IonicModule } from '@ionic/angular'
|
||||
import { AppListPage } from './app-list.page'
|
||||
import { StatusComponentModule } from 'src/app/components/status/status.component.module'
|
||||
import { SharingModule } from 'src/app/modules/sharing.module'
|
||||
import {
|
||||
EmverPipesModule,
|
||||
TextSpinnerComponentModule,
|
||||
} from '@start9labs/shared'
|
||||
import { BadgeMenuComponentModule } from 'src/app/components/badge-menu-button/badge-menu.component.module'
|
||||
import { StatusComponentModule } from 'src/app/components/status/status.component.module'
|
||||
import { LaunchablePipeModule } from 'src/app/pipes/launchable/launchable.module'
|
||||
import { UiPipeModule } from 'src/app/pipes/ui/ui.module'
|
||||
import { AppListIconComponent } from './app-list-icon/app-list-icon.component'
|
||||
import { AppListEmptyComponent } from './app-list-empty/app-list-empty.component'
|
||||
import { AppListPkgComponent } from './app-list-pkg/app-list-pkg.component'
|
||||
@@ -24,7 +29,10 @@ const routes: Routes = [
|
||||
imports: [
|
||||
CommonModule,
|
||||
StatusComponentModule,
|
||||
SharingModule,
|
||||
EmverPipesModule,
|
||||
TextSpinnerComponentModule,
|
||||
LaunchablePipeModule,
|
||||
UiPipeModule,
|
||||
IonicModule,
|
||||
RouterModule.forChild(routes),
|
||||
BadgeMenuComponentModule,
|
||||
@@ -39,4 +47,4 @@ const routes: Routes = [
|
||||
PackageInfoPipe,
|
||||
],
|
||||
})
|
||||
export class AppListPageModule { }
|
||||
export class AppListPageModule {}
|
||||
|
||||
@@ -3,10 +3,9 @@ import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
||||
import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
|
||||
import { Observable } from 'rxjs'
|
||||
import { filter, map, switchMapTo, take, takeUntil, tap } from 'rxjs/operators'
|
||||
import { isEmptyObject, exists } from 'src/app/util/misc.util'
|
||||
import { isEmptyObject, exists, DestroyService } from '@start9labs/shared'
|
||||
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||
import { parseDataModel, RecoveredInfo } from 'src/app/util/parse-data-model'
|
||||
import { DestroyService } from 'src/app/services/destroy.service'
|
||||
|
||||
@Component({
|
||||
selector: 'app-list',
|
||||
@@ -20,21 +19,21 @@ export class AppListPage {
|
||||
order: readonly string[] = []
|
||||
reordering = false
|
||||
|
||||
constructor (
|
||||
constructor(
|
||||
private readonly api: ApiService,
|
||||
private readonly destroy$: DestroyService,
|
||||
public readonly patch: PatchDbService,
|
||||
) { }
|
||||
) {}
|
||||
|
||||
get empty (): boolean {
|
||||
get empty(): boolean {
|
||||
return !this.pkgs.length && isEmptyObject(this.recoveredPkgs)
|
||||
}
|
||||
|
||||
ngOnInit () {
|
||||
ngOnInit() {
|
||||
this.patch
|
||||
.watch$()
|
||||
.pipe(
|
||||
filter((data) => exists(data) && !isEmptyObject(data)),
|
||||
filter(data => exists(data) && !isEmptyObject(data)),
|
||||
take(1),
|
||||
map(parseDataModel),
|
||||
tap(({ order, pkgs, recoveredPkgs }) => {
|
||||
@@ -53,7 +52,7 @@ export class AppListPage {
|
||||
.subscribe()
|
||||
}
|
||||
|
||||
onReordering (reordering: boolean): void {
|
||||
onReordering(reordering: boolean): void {
|
||||
if (!reordering) {
|
||||
this.setOrder()
|
||||
}
|
||||
@@ -61,35 +60,33 @@ export class AppListPage {
|
||||
this.reordering = reordering
|
||||
}
|
||||
|
||||
deleteRecovered (rec: RecoveredInfo): void {
|
||||
this.recoveredPkgs = this.recoveredPkgs.filter((item) => item !== rec)
|
||||
deleteRecovered(rec: RecoveredInfo): void {
|
||||
this.recoveredPkgs = this.recoveredPkgs.filter(item => item !== rec)
|
||||
}
|
||||
|
||||
private watchNewlyRecovered (): Observable<unknown> {
|
||||
private watchNewlyRecovered(): Observable<unknown> {
|
||||
return this.patch.watch$('package-data').pipe(
|
||||
filter((pkgs) => !!pkgs && Object.keys(pkgs).length !== this.pkgs.length),
|
||||
tap((pkgs) => {
|
||||
filter(pkgs => !!pkgs && Object.keys(pkgs).length !== this.pkgs.length),
|
||||
tap(pkgs => {
|
||||
const ids = Object.keys(pkgs)
|
||||
const newIds = ids.filter(
|
||||
(id) => !this.pkgs.find((pkg) => pkg.manifest.id === id),
|
||||
id => !this.pkgs.find(pkg => pkg.manifest.id === id),
|
||||
)
|
||||
|
||||
// remove uninstalled
|
||||
const filtered = this.pkgs.filter((pkg) =>
|
||||
ids.includes(pkg.manifest.id),
|
||||
)
|
||||
const filtered = this.pkgs.filter(pkg => ids.includes(pkg.manifest.id))
|
||||
|
||||
// add new entry to beginning of array
|
||||
const added = newIds.map((id) => pkgs[id])
|
||||
const added = newIds.map(id => pkgs[id])
|
||||
|
||||
this.pkgs = [...added, ...filtered]
|
||||
this.recoveredPkgs = this.recoveredPkgs.filter((rec) => !pkgs[rec.id])
|
||||
this.recoveredPkgs = this.recoveredPkgs.filter(rec => !pkgs[rec.id])
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
private setOrder (): void {
|
||||
this.order = this.pkgs.map((pkg) => pkg.manifest.id)
|
||||
private setOrder(): void {
|
||||
this.order = this.pkgs.map(pkg => pkg.manifest.id)
|
||||
this.api.setDbValue({ pointer: '/pkg-order', value: this.order })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
import { Pipe, PipeTransform } from "@angular/core";
|
||||
import { Observable } from "rxjs";
|
||||
import { filter, map, startWith } from "rxjs/operators";
|
||||
import { PackageDataEntry } from "../../../services/patch-db/data-model";
|
||||
import { getPackageInfo, PkgInfo } from "../../../util/get-package-info";
|
||||
import { PatchDbService } from "../../../services/patch-db/patch-db.service";
|
||||
import { Pipe, PipeTransform } from '@angular/core'
|
||||
import { Observable } from 'rxjs'
|
||||
import { filter, map, startWith } from 'rxjs/operators'
|
||||
import { PackageDataEntry } from '../../../services/patch-db/data-model'
|
||||
import { getPackageInfo, PkgInfo } from '../../../util/get-package-info'
|
||||
import { PatchDbService } from '../../../services/patch-db/patch-db.service'
|
||||
|
||||
@Pipe({
|
||||
name: "packageInfo",
|
||||
name: 'packageInfo',
|
||||
})
|
||||
export class PackageInfoPipe implements PipeTransform {
|
||||
constructor(private readonly patch: PatchDbService) {}
|
||||
|
||||
transform(pkg: PackageDataEntry): Observable<PkgInfo> {
|
||||
return this.patch.watch$("package-data", pkg.manifest.id).pipe(
|
||||
filter((v) => !!v),
|
||||
return this.patch.watch$('package-data', pkg.manifest.id).pipe(
|
||||
filter(v => !!v),
|
||||
map(getPackageInfo),
|
||||
startWith(getPackageInfo(pkg))
|
||||
);
|
||||
startWith(getPackageInfo(pkg)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common'
|
||||
import { Routes, RouterModule } from '@angular/router'
|
||||
import { IonicModule } from '@ionic/angular'
|
||||
import { AppLogsPage } from './app-logs.page'
|
||||
import { SharingModule } from 'src/app/modules/sharing.module'
|
||||
import { SharedPipesModule } from '@start9labs/shared'
|
||||
import { LogsPageModule } from 'src/app/components/logs/logs.module'
|
||||
|
||||
const routes: Routes = [
|
||||
@@ -18,9 +18,9 @@ const routes: Routes = [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
RouterModule.forChild(routes),
|
||||
SharingModule,
|
||||
SharedPipesModule,
|
||||
LogsPageModule,
|
||||
],
|
||||
declarations: [AppLogsPage],
|
||||
})
|
||||
export class AppLogsPageModule { }
|
||||
export class AppLogsPageModule {}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common'
|
||||
import { Routes, RouterModule } from '@angular/router'
|
||||
import { IonicModule } from '@ionic/angular'
|
||||
import { AppMetricsPage } from './app-metrics.page'
|
||||
import { SharingModule } from 'src/app/modules/sharing.module'
|
||||
import { SharedPipesModule } from '@start9labs/shared'
|
||||
import { SkeletonListComponentModule } from 'src/app/components/skeleton-list/skeleton-list.component.module'
|
||||
|
||||
const routes: Routes = [
|
||||
@@ -18,9 +18,9 @@ const routes: Routes = [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
RouterModule.forChild(routes),
|
||||
SharingModule,
|
||||
SharedPipesModule,
|
||||
SkeletonListComponentModule,
|
||||
],
|
||||
declarations: [AppMetricsPage],
|
||||
})
|
||||
export class AppMetricsPageModule { }
|
||||
export class AppMetricsPageModule {}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { Metric } from 'src/app/services/api/api.types'
|
||||
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||
import { ErrorToastService } from 'src/app/services/error-toast.service'
|
||||
import { MainStatus } from 'src/app/services/patch-db/data-model'
|
||||
import { pauseFor } from 'src/app/util/misc.util'
|
||||
import { pauseFor } from '@start9labs/shared'
|
||||
|
||||
@Component({
|
||||
selector: 'app-metrics',
|
||||
@@ -23,26 +23,26 @@ export class AppMetricsPage {
|
||||
|
||||
@ViewChild(IonContent) content: IonContent
|
||||
|
||||
constructor (
|
||||
constructor(
|
||||
private readonly route: ActivatedRoute,
|
||||
private readonly errToast: ErrorToastService,
|
||||
private readonly embassyApi: ApiService,
|
||||
) { }
|
||||
) {}
|
||||
|
||||
ngOnInit () {
|
||||
ngOnInit() {
|
||||
this.pkgId = this.route.snapshot.paramMap.get('pkgId')
|
||||
this.startDaemon()
|
||||
}
|
||||
|
||||
ngAfterViewInit () {
|
||||
ngAfterViewInit() {
|
||||
this.content.scrollToPoint(undefined, 1)
|
||||
}
|
||||
|
||||
ngOnDestroy () {
|
||||
ngOnDestroy() {
|
||||
this.stopDaemon()
|
||||
}
|
||||
|
||||
async startDaemon (): Promise<void> {
|
||||
async startDaemon(): Promise<void> {
|
||||
this.going = true
|
||||
while (this.going) {
|
||||
const startTime = Date.now()
|
||||
@@ -51,13 +51,13 @@ export class AppMetricsPage {
|
||||
}
|
||||
}
|
||||
|
||||
stopDaemon () {
|
||||
stopDaemon() {
|
||||
this.going = false
|
||||
}
|
||||
|
||||
async getMetrics (): Promise<void> {
|
||||
async getMetrics(): Promise<void> {
|
||||
try {
|
||||
this.metrics = await this.embassyApi.getPkgMetrics({ id: this.pkgId})
|
||||
this.metrics = await this.embassyApi.getPkgMetrics({ id: this.pkgId })
|
||||
} catch (e) {
|
||||
this.errToast.present(e)
|
||||
this.stopDaemon()
|
||||
@@ -66,7 +66,7 @@ export class AppMetricsPage {
|
||||
}
|
||||
}
|
||||
|
||||
asIsOrder (a: any, b: any) {
|
||||
asIsOrder(a: any, b: any) {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,11 @@ import { Routes, RouterModule } from '@angular/router'
|
||||
import { IonicModule } from '@ionic/angular'
|
||||
import { AppPropertiesPage } from './app-properties.page'
|
||||
import { QRComponentModule } from 'src/app/components/qr/qr.component.module'
|
||||
import { SharingModule } from 'src/app/modules/sharing.module'
|
||||
import { MaskPipeModule } from 'src/app/pipes/mask/mask.module'
|
||||
import {
|
||||
SharedPipesModule,
|
||||
TextSpinnerComponentModule,
|
||||
} from '@start9labs/shared'
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
@@ -19,8 +23,10 @@ const routes: Routes = [
|
||||
IonicModule,
|
||||
RouterModule.forChild(routes),
|
||||
QRComponentModule,
|
||||
SharingModule,
|
||||
SharedPipesModule,
|
||||
TextSpinnerComponentModule,
|
||||
MaskPipeModule,
|
||||
],
|
||||
declarations: [AppPropertiesPage],
|
||||
})
|
||||
export class AppPropertiesPageModule { }
|
||||
export class AppPropertiesPageModule {}
|
||||
|
||||
@@ -3,7 +3,13 @@ import { ActivatedRoute } from '@angular/router'
|
||||
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||
import { Subscription } from 'rxjs'
|
||||
import { copyToClipboard } from 'src/app/util/web.util'
|
||||
import { AlertController, IonContent, ModalController, NavController, ToastController } from '@ionic/angular'
|
||||
import {
|
||||
AlertController,
|
||||
IonContent,
|
||||
ModalController,
|
||||
NavController,
|
||||
ToastController,
|
||||
} from '@ionic/angular'
|
||||
import { PackageProperties } from 'src/app/util/properties.util'
|
||||
import { QRComponent } from 'src/app/components/qr/qr.component'
|
||||
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
||||
@@ -22,13 +28,13 @@ export class AppPropertiesPage {
|
||||
pointer: string
|
||||
properties: PackageProperties
|
||||
node: PackageProperties
|
||||
unmasked: { [key: string]: boolean } = { }
|
||||
unmasked: { [key: string]: boolean } = {}
|
||||
running = true
|
||||
|
||||
@ViewChild(IonContent) content: IonContent
|
||||
subs: Subscription[] = []
|
||||
|
||||
constructor (
|
||||
constructor(
|
||||
private readonly route: ActivatedRoute,
|
||||
private readonly embassyApi: ApiService,
|
||||
private readonly errToast: ErrorToastService,
|
||||
@@ -37,40 +43,50 @@ export class AppPropertiesPage {
|
||||
private readonly modalCtrl: ModalController,
|
||||
private readonly navCtrl: NavController,
|
||||
private readonly patch: PatchDbService,
|
||||
) { }
|
||||
) {}
|
||||
|
||||
async ngOnInit () {
|
||||
async ngOnInit() {
|
||||
this.pkgId = this.route.snapshot.paramMap.get('pkgId')
|
||||
|
||||
await this.getProperties()
|
||||
|
||||
this.subs = [
|
||||
this.route.queryParams
|
||||
.subscribe(queryParams => {
|
||||
this.route.queryParams.subscribe(queryParams => {
|
||||
if (queryParams['pointer'] === this.pointer) return
|
||||
this.pointer = queryParams['pointer']
|
||||
this.node = getValueByPointer(this.properties, this.pointer || '')
|
||||
}),
|
||||
this.patch.watch$('package-data', this.pkgId, 'installed', 'status', 'main', 'status')
|
||||
.subscribe(status => {
|
||||
this.running = status === PackageMainStatus.Running
|
||||
}),
|
||||
this.patch
|
||||
.watch$(
|
||||
'package-data',
|
||||
this.pkgId,
|
||||
'installed',
|
||||
'status',
|
||||
'main',
|
||||
'status',
|
||||
)
|
||||
.subscribe(status => {
|
||||
this.running = status === PackageMainStatus.Running
|
||||
}),
|
||||
]
|
||||
}
|
||||
|
||||
ngAfterViewInit () {
|
||||
ngAfterViewInit() {
|
||||
this.content.scrollToPoint(undefined, 1)
|
||||
}
|
||||
|
||||
ngOnDestroy () {
|
||||
ngOnDestroy() {
|
||||
this.subs.forEach(sub => sub.unsubscribe())
|
||||
}
|
||||
|
||||
async refresh () {
|
||||
async refresh() {
|
||||
await this.getProperties()
|
||||
}
|
||||
|
||||
async presentDescription (property: { key: string, value: PackageProperties[''] }, e: Event) {
|
||||
async presentDescription(
|
||||
property: { key: string; value: PackageProperties[''] },
|
||||
e: Event,
|
||||
) {
|
||||
e.stopPropagation()
|
||||
|
||||
const alert = await this.alertCtrl.create({
|
||||
@@ -80,7 +96,7 @@ export class AppPropertiesPage {
|
||||
await alert.present()
|
||||
}
|
||||
|
||||
async goToNested (key: string): Promise<any> {
|
||||
async goToNested(key: string): Promise<any> {
|
||||
this.navCtrl.navigateForward(`/services/${this.pkgId}/properties`, {
|
||||
queryParams: {
|
||||
pointer: `${this.pointer || ''}/${key}/value`,
|
||||
@@ -88,9 +104,11 @@ export class AppPropertiesPage {
|
||||
})
|
||||
}
|
||||
|
||||
async copy (text: string): Promise<void> {
|
||||
async copy(text: string): Promise<void> {
|
||||
let message = ''
|
||||
await copyToClipboard(text).then(success => { message = success ? 'copied to clipboard!' : 'failed to copy'})
|
||||
await copyToClipboard(text).then(success => {
|
||||
message = success ? 'copied to clipboard!' : 'failed to copy'
|
||||
})
|
||||
|
||||
const toast = await this.toastCtrl.create({
|
||||
header: message,
|
||||
@@ -100,7 +118,7 @@ export class AppPropertiesPage {
|
||||
await toast.present()
|
||||
}
|
||||
|
||||
async showQR (text: string): Promise<void> {
|
||||
async showQR(text: string): Promise<void> {
|
||||
const modal = await this.modalCtrl.create({
|
||||
component: QRComponent,
|
||||
componentProps: {
|
||||
@@ -111,14 +129,16 @@ export class AppPropertiesPage {
|
||||
await modal.present()
|
||||
}
|
||||
|
||||
toggleMask (key: string) {
|
||||
toggleMask(key: string) {
|
||||
this.unmasked[key] = !this.unmasked[key]
|
||||
}
|
||||
|
||||
private async getProperties (): Promise<void> {
|
||||
private async getProperties(): Promise<void> {
|
||||
this.loading = true
|
||||
try {
|
||||
this.properties = await this.embassyApi.getPackageProperties({ id: this.pkgId })
|
||||
this.properties = await this.embassyApi.getPackageProperties({
|
||||
id: this.pkgId,
|
||||
})
|
||||
this.node = getValueByPointer(this.properties, this.pointer || '')
|
||||
} catch (e) {
|
||||
this.errToast.present(e)
|
||||
@@ -127,7 +147,7 @@ export class AppPropertiesPage {
|
||||
}
|
||||
}
|
||||
|
||||
asIsOrder (a: any, b: any) {
|
||||
asIsOrder(a: any, b: any) {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,10 +3,12 @@ import { CommonModule } from '@angular/common'
|
||||
import { Routes, RouterModule } from '@angular/router'
|
||||
import { IonicModule } from '@ionic/angular'
|
||||
import { AppShowPage } from './app-show.page'
|
||||
import { StatusComponentModule } from 'src/app/components/status/status.component.module'
|
||||
import { SharingModule } from 'src/app/modules/sharing.module'
|
||||
import { EmverPipesModule } from '@start9labs/shared'
|
||||
import { InstallWizardComponentModule } from 'src/app/components/install-wizard/install-wizard.component.module'
|
||||
import { StatusComponentModule } from 'src/app/components/status/status.component.module'
|
||||
import { AppConfigPageModule } from 'src/app/modals/app-config/app-config.module'
|
||||
import { LaunchablePipeModule } from 'src/app/pipes/launchable/launchable.module'
|
||||
import { UiPipeModule } from 'src/app/pipes/ui/ui.module'
|
||||
import { AppShowHeaderComponent } from './components/app-show-header/app-show-header.component'
|
||||
import { AppShowProgressComponent } from './components/app-show-progress/app-show-progress.component'
|
||||
import { AppShowStatusComponent } from './components/app-show-status/app-show-status.component'
|
||||
@@ -18,6 +20,7 @@ import { ToHealthChecksPipe } from './pipes/to-health-checks.pipe'
|
||||
import { ToButtonsPipe } from './pipes/to-buttons.pipe'
|
||||
import { ToDependenciesPipe } from './pipes/to-dependencies.pipe'
|
||||
import { ToStatusPipe } from './pipes/to-status.pipe'
|
||||
import { InstallStatePipe } from './pipes/install-state.pipe'
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
@@ -30,6 +33,7 @@ const routes: Routes = [
|
||||
declarations: [
|
||||
AppShowPage,
|
||||
HealthColorPipe,
|
||||
InstallStatePipe,
|
||||
ToHealthChecksPipe,
|
||||
ToButtonsPipe,
|
||||
ToDependenciesPipe,
|
||||
@@ -48,7 +52,9 @@ const routes: Routes = [
|
||||
RouterModule.forChild(routes),
|
||||
InstallWizardComponentModule,
|
||||
AppConfigPageModule,
|
||||
SharingModule,
|
||||
EmverPipesModule,
|
||||
LaunchablePipeModule,
|
||||
UiPipeModule,
|
||||
],
|
||||
})
|
||||
export class AppShowPageModule {}
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core'
|
||||
import { NavController } from '@ionic/angular'
|
||||
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
||||
import {
|
||||
PackageDataEntry,
|
||||
PackageState,
|
||||
} from 'src/app/services/patch-db/data-model'
|
||||
import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
|
||||
import { PackageState } from '@start9labs/shared'
|
||||
import {
|
||||
PackageStatus,
|
||||
PrimaryStatus,
|
||||
@@ -70,4 +68,3 @@ export class AppShowPage {
|
||||
return STATES.includes(state)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
|
||||
import {
|
||||
InstallProgress,
|
||||
PackageDataEntry,
|
||||
} from 'src/app/services/patch-db/data-model'
|
||||
import { ProgressData } from 'src/app/util/package-loading-progress'
|
||||
import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
|
||||
import { InstallProgress, ProgressData } from '@start9labs/shared'
|
||||
|
||||
@Component({
|
||||
selector: 'app-show-progress',
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
|
||||
import { UiLauncherService } from 'src/app/services/ui-launcher.service'
|
||||
import {
|
||||
InterfaceDef,
|
||||
PackageDataEntry,
|
||||
PackageState,
|
||||
Status,
|
||||
} from 'src/app/services/patch-db/data-model'
|
||||
import {
|
||||
PackageStatus,
|
||||
PrimaryRendering,
|
||||
PrimaryStatus,
|
||||
} from 'src/app/services/pkg-status-rendering.service'
|
||||
import { isEmptyObject } from 'src/app/util/misc.util'
|
||||
import {
|
||||
InterfaceDef,
|
||||
PackageDataEntry,
|
||||
Status,
|
||||
} from 'src/app/services/patch-db/data-model'
|
||||
import { isEmptyObject, PackageState } from '@start9labs/shared'
|
||||
import { wizardModal } from 'src/app/components/install-wizard/install-wizard.component'
|
||||
import {
|
||||
AlertController,
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core'
|
||||
import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
|
||||
import { ProgressData, packageLoadingProgress } from '@start9labs/shared'
|
||||
|
||||
@Pipe({
|
||||
name: 'installState',
|
||||
})
|
||||
export class InstallStatePipe implements PipeTransform {
|
||||
transform(pkg: PackageDataEntry): ProgressData | null {
|
||||
return packageLoadingProgress(pkg['install-progress'])
|
||||
}
|
||||
}
|
||||
@@ -84,7 +84,8 @@ export class ToButtonsPipe implements PipeTransform {
|
||||
},
|
||||
// view in marketplace
|
||||
{
|
||||
action: () => this.navCtrl.navigateForward([`marketplace/${pkg.manifest.id}`]),
|
||||
action: () =>
|
||||
this.navCtrl.navigateForward([`marketplace/${pkg.manifest.id}`]),
|
||||
title: 'Marketplace',
|
||||
description: 'View service in marketplace',
|
||||
icon: 'storefront-outline',
|
||||
|
||||
@@ -3,12 +3,12 @@ import { NavigationExtras } from '@angular/router'
|
||||
import { NavController } from '@ionic/angular'
|
||||
import { combineLatest, Observable } from 'rxjs'
|
||||
import { filter, map, startWith } from 'rxjs/operators'
|
||||
import { DependentInfo, exists } from 'src/app/util/misc.util'
|
||||
import {
|
||||
DependencyError,
|
||||
DependencyErrorType,
|
||||
PackageDataEntry,
|
||||
} from 'src/app/services/patch-db/data-model'
|
||||
import { DependentInfo, exists } from '@start9labs/shared'
|
||||
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
||||
import { ModalService } from 'src/app/services/modal.service'
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Inject, Pipe, PipeTransform } from '@angular/core'
|
||||
import { Pipe, PipeTransform } from '@angular/core'
|
||||
import {
|
||||
HealthCheckResult,
|
||||
PackageDataEntry,
|
||||
PackageMainStatus,
|
||||
} from 'src/app/services/patch-db/data-model'
|
||||
import { exists, isEmptyObject } from 'src/app/util/misc.util'
|
||||
import { exists, isEmptyObject } from '@start9labs/shared'
|
||||
import { filter, map, startWith } from 'rxjs/operators'
|
||||
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
||||
import { Observable } from 'rxjs'
|
||||
@@ -30,7 +30,8 @@ export class ToHealthChecksPipe implements PipeTransform {
|
||||
map(main => {
|
||||
// Question: is this ok or do we have to use Object.keys
|
||||
// to maintain order and the keys initially present in pkg?
|
||||
return main.status === PackageMainStatus.Running && !isEmptyObject(main.health)
|
||||
return main.status === PackageMainStatus.Running &&
|
||||
!isEmptyObject(main.health)
|
||||
? main.health
|
||||
: healthChecks
|
||||
}),
|
||||
|
||||
@@ -4,7 +4,6 @@ import { IonicModule } from '@ionic/angular'
|
||||
import { RouterModule, Routes } from '@angular/router'
|
||||
import { DevConfigPage } from './dev-config.page'
|
||||
import { BadgeMenuComponentModule } from 'src/app/components/badge-menu-button/badge-menu.component.module'
|
||||
import { SharingModule } from 'src/app/modules/sharing.module'
|
||||
import { BackupReportPageModule } from 'src/app/modals/backup-report/backup-report.module'
|
||||
import { FormsModule } from '@angular/forms'
|
||||
import { MonacoEditorModule } from '@materia-ui/ngx-monaco-editor'
|
||||
@@ -22,7 +21,6 @@ const routes: Routes = [
|
||||
IonicModule,
|
||||
RouterModule.forChild(routes),
|
||||
BadgeMenuComponentModule,
|
||||
SharingModule,
|
||||
BackupReportPageModule,
|
||||
FormsModule,
|
||||
MonacoEditorModule,
|
||||
|
||||
@@ -4,7 +4,6 @@ import { IonicModule } from '@ionic/angular'
|
||||
import { RouterModule, Routes } from '@angular/router'
|
||||
import { DevInstructionsPage } from './dev-instructions.page'
|
||||
import { BadgeMenuComponentModule } from 'src/app/components/badge-menu-button/badge-menu.component.module'
|
||||
import { SharingModule } from 'src/app/modules/sharing.module'
|
||||
import { BackupReportPageModule } from 'src/app/modals/backup-report/backup-report.module'
|
||||
import { FormsModule } from '@angular/forms'
|
||||
import { MonacoEditorModule } from '@materia-ui/ngx-monaco-editor'
|
||||
@@ -22,7 +21,6 @@ const routes: Routes = [
|
||||
IonicModule,
|
||||
RouterModule.forChild(routes),
|
||||
BadgeMenuComponentModule,
|
||||
SharingModule,
|
||||
BackupReportPageModule,
|
||||
FormsModule,
|
||||
MonacoEditorModule,
|
||||
|
||||
@@ -4,7 +4,6 @@ import { IonicModule } from '@ionic/angular'
|
||||
import { RouterModule, Routes } from '@angular/router'
|
||||
import { DeveloperPage } from './developer-list.page'
|
||||
import { BadgeMenuComponentModule } from 'src/app/components/badge-menu-button/badge-menu.component.module'
|
||||
import { SharingModule } from 'src/app/modules/sharing.module'
|
||||
import { BackupReportPageModule } from 'src/app/modals/backup-report/backup-report.module'
|
||||
|
||||
const routes: Routes = [
|
||||
@@ -20,7 +19,6 @@ const routes: Routes = [
|
||||
IonicModule,
|
||||
RouterModule.forChild(routes),
|
||||
BadgeMenuComponentModule,
|
||||
SharingModule,
|
||||
BackupReportPageModule,
|
||||
],
|
||||
declarations: [DeveloperPage],
|
||||
|
||||
@@ -4,7 +4,7 @@ import { CommonModule } from '@angular/common'
|
||||
import { FormsModule } from '@angular/forms'
|
||||
import { IonicModule } from '@ionic/angular'
|
||||
import { LoginPage } from './login.page'
|
||||
import { SharingModule } from 'src/app/modules/sharing.module'
|
||||
import { SharedPipesModule } from '@start9labs/shared'
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
@@ -19,8 +19,8 @@ const routes: Routes = [
|
||||
FormsModule,
|
||||
IonicModule,
|
||||
RouterModule.forChild(routes),
|
||||
SharingModule,
|
||||
SharedPipesModule,
|
||||
],
|
||||
declarations: [LoginPage],
|
||||
})
|
||||
export class LoginPageModule { }
|
||||
export class LoginPageModule {}
|
||||
|
||||
@@ -2,8 +2,13 @@ import { NgModule } from '@angular/core'
|
||||
import { CommonModule } from '@angular/common'
|
||||
import { Routes, RouterModule } from '@angular/router'
|
||||
import { IonicModule } from '@ionic/angular'
|
||||
import {
|
||||
EmverPipesModule,
|
||||
MarkdownPipeModule,
|
||||
TextSpinnerComponentModule,
|
||||
} from '@start9labs/shared'
|
||||
import { AppReleaseNotes } from './app-release-notes.page'
|
||||
import { SharingModule } from 'src/app/modules/sharing.module'
|
||||
import { MarketplacePipesModule } from '../pipes/marketplace-pipes.module'
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
@@ -17,8 +22,11 @@ const routes: Routes = [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
RouterModule.forChild(routes),
|
||||
SharingModule,
|
||||
TextSpinnerComponentModule,
|
||||
EmverPipesModule,
|
||||
MarkdownPipeModule,
|
||||
MarketplacePipesModule,
|
||||
],
|
||||
declarations: [AppReleaseNotes],
|
||||
})
|
||||
export class ReleaseNotesModule { }
|
||||
export class ReleaseNotesModule {}
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
import { NgModule } from '@angular/core'
|
||||
import { CommonModule } from '@angular/common'
|
||||
import { FormsModule } from '@angular/forms'
|
||||
import { Routes, RouterModule } from '@angular/router'
|
||||
import { IonicModule } from '@ionic/angular'
|
||||
import { MarketplaceListPage } from './marketplace-list.page'
|
||||
import { SharingModule } from '../../../modules/sharing.module'
|
||||
import {
|
||||
SharedPipesModule,
|
||||
EmverPipesModule,
|
||||
TextSpinnerComponentModule,
|
||||
} from '@start9labs/shared'
|
||||
import { BadgeMenuComponentModule } from 'src/app/components/badge-menu-button/badge-menu.component.module'
|
||||
import { StatusComponentModule } from 'src/app/components/status/status.component.module'
|
||||
import { FormsModule } from '@angular/forms'
|
||||
import { MarketplacePipesModule } from '../pipes/marketplace-pipes.module'
|
||||
import { MarketplaceListPage } from './marketplace-list.page'
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
@@ -21,10 +25,12 @@ const routes: Routes = [
|
||||
IonicModule,
|
||||
FormsModule,
|
||||
RouterModule.forChild(routes),
|
||||
StatusComponentModule,
|
||||
SharingModule,
|
||||
TextSpinnerComponentModule,
|
||||
SharedPipesModule,
|
||||
EmverPipesModule,
|
||||
MarketplacePipesModule,
|
||||
BadgeMenuComponentModule,
|
||||
],
|
||||
declarations: [MarketplaceListPage],
|
||||
})
|
||||
export class MarketplaceListPageModule { }
|
||||
export class MarketplaceListPageModule {}
|
||||
|
||||
@@ -122,7 +122,7 @@
|
||||
<ion-col *ngFor="let pkg of pkgs" sizeXs="12" sizeSm="12" sizeMd="6">
|
||||
<ion-item [routerLink]="['/marketplace', pkg.manifest.id]">
|
||||
<ion-thumbnail slot="start">
|
||||
<img [src]="('data:image/png;base64,' + pkg.icon) | sanitize" />
|
||||
<img [src]="('data:image/png;base64,' + pkg.icon) | trust" />
|
||||
</ion-thumbnail>
|
||||
<ion-label>
|
||||
<h2 style="font-family: 'Montserrat'; font-weight: bold">
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
import { Component, ViewChild } from '@angular/core'
|
||||
import { MarketplacePkg } from 'src/app/services/api/api.types'
|
||||
import { IonContent } from '@ionic/angular'
|
||||
import {
|
||||
PackageDataEntry,
|
||||
PackageState,
|
||||
} from 'src/app/services/patch-db/data-model'
|
||||
import { Subscription } from 'rxjs'
|
||||
import { ErrorToastService } from 'src/app/services/error-toast.service'
|
||||
import { MarketplaceService } from '../marketplace.service'
|
||||
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
||||
import Fuse from 'fuse.js/dist/fuse.min.js'
|
||||
import { exists, isEmptyObject } from 'src/app/util/misc.util'
|
||||
import { exists, isEmptyObject, PackageState } from '@start9labs/shared'
|
||||
import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
|
||||
import { filter, first } from 'rxjs/operators'
|
||||
|
||||
const defaultOps = {
|
||||
@@ -46,7 +43,7 @@ export class MarketplaceListPage {
|
||||
|
||||
pkgs: MarketplacePkg[] = []
|
||||
categories: string[]
|
||||
localPkgs: { [id: string]: PackageDataEntry } = {}
|
||||
localPkgs: Record<string, PackageDataEntry> = {}
|
||||
category = 'featured'
|
||||
query: string
|
||||
loading = true
|
||||
|
||||
@@ -3,9 +3,14 @@ import { CommonModule } from '@angular/common'
|
||||
import { Routes, RouterModule } from '@angular/router'
|
||||
import { IonicModule } from '@ionic/angular'
|
||||
import { MarketplaceShowPage } from './marketplace-show.page'
|
||||
import { SharingModule } from 'src/app/modules/sharing.module'
|
||||
import { StatusComponentModule } from 'src/app/components/status/status.component.module'
|
||||
import {
|
||||
SharedPipesModule,
|
||||
EmverPipesModule,
|
||||
MarkdownPipeModule,
|
||||
TextSpinnerComponentModule,
|
||||
} from '@start9labs/shared'
|
||||
import { InstallWizardComponentModule } from 'src/app/components/install-wizard/install-wizard.component.module'
|
||||
import { MarketplacePipesModule } from '../pipes/marketplace-pipes.module'
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
@@ -18,11 +23,14 @@ const routes: Routes = [
|
||||
imports: [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
StatusComponentModule,
|
||||
RouterModule.forChild(routes),
|
||||
SharingModule,
|
||||
TextSpinnerComponentModule,
|
||||
SharedPipesModule,
|
||||
EmverPipesModule,
|
||||
MarkdownPipeModule,
|
||||
MarketplacePipesModule,
|
||||
InstallWizardComponentModule,
|
||||
],
|
||||
declarations: [MarketplaceShowPage],
|
||||
})
|
||||
export class MarketplaceShowPageModule { }
|
||||
export class MarketplaceShowPageModule {}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<ion-row>
|
||||
<ion-col sizeXs="12" sizeSm="12" sizeMd="9" sizeLg="9" sizeXl="9">
|
||||
<div class="header">
|
||||
<img [src]="('data:image/png;base64,' + pkg.icon) | sanitize" />
|
||||
<img [src]="('data:image/png;base64,' + pkg.icon) | trust" />
|
||||
<div class="header-text">
|
||||
<h1 class="header-title">{{ pkg.manifest.title }}</h1>
|
||||
<p class="header-version">
|
||||
@@ -198,7 +198,7 @@
|
||||
<ion-item [routerLink]="['/marketplace', dep.key]">
|
||||
<ion-thumbnail slot="start">
|
||||
<img
|
||||
[src]="('data:image/png;base64,' + pkg['dependency-metadata'][dep.key].icon) | sanitize"
|
||||
[src]="('data:image/png;base64,' + pkg['dependency-metadata'][dep.key].icon) | trust"
|
||||
/>
|
||||
</ion-thumbnail>
|
||||
<ion-label>
|
||||
|
||||
@@ -9,15 +9,16 @@ import {
|
||||
} from '@ionic/angular'
|
||||
import { wizardModal } from 'src/app/components/install-wizard/install-wizard.component'
|
||||
import { WizardBaker } from 'src/app/components/install-wizard/prebaked-wizards'
|
||||
import { Emver } from 'src/app/services/emver.service'
|
||||
import { displayEmver } from 'src/app/pipes/emver.pipe'
|
||||
import { DependentInfo, pauseFor } from 'src/app/util/misc.util'
|
||||
import {
|
||||
displayEmver,
|
||||
Emver,
|
||||
DependentInfo,
|
||||
pauseFor,
|
||||
PackageState,
|
||||
} from '@start9labs/shared'
|
||||
import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
|
||||
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
||||
import { ErrorToastService } from 'src/app/services/error-toast.service'
|
||||
import {
|
||||
PackageDataEntry,
|
||||
PackageState,
|
||||
} from 'src/app/services/patch-db/data-model'
|
||||
import { MarketplaceService } from '../marketplace.service'
|
||||
import { Subscription } from 'rxjs'
|
||||
import { MarkdownPage } from 'src/app/modals/markdown/markdown.page'
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
} from 'src/app/services/api/api.types'
|
||||
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||
import { ConfigService } from 'src/app/services/config.service'
|
||||
import { Emver } from 'src/app/services/emver.service'
|
||||
import { Emver } from '@start9labs/shared'
|
||||
import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
|
||||
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
||||
|
||||
@@ -24,14 +24,14 @@ export class MarketplaceService {
|
||||
} = {}
|
||||
marketplaceUrl: string
|
||||
|
||||
constructor (
|
||||
constructor(
|
||||
private readonly api: ApiService,
|
||||
private readonly emver: Emver,
|
||||
private readonly patch: PatchDbService,
|
||||
private readonly config: ConfigService,
|
||||
) { }
|
||||
) {}
|
||||
|
||||
init (): Subscription {
|
||||
init(): Subscription {
|
||||
return this.patch.watch$('ui', 'marketplace').subscribe(marketplace => {
|
||||
if (!marketplace || !marketplace['selected-id']) {
|
||||
this.marketplaceUrl = this.config.marketplace.url
|
||||
@@ -42,7 +42,7 @@ export class MarketplaceService {
|
||||
})
|
||||
}
|
||||
|
||||
async load (): Promise<void> {
|
||||
async load(): Promise<void> {
|
||||
try {
|
||||
const [data, pkgs] = await Promise.all([
|
||||
this.getMarketplaceData({}),
|
||||
@@ -67,9 +67,9 @@ export class MarketplaceService {
|
||||
}
|
||||
}
|
||||
|
||||
async getUpdates (localPkgs: {
|
||||
[id: string]: PackageDataEntry
|
||||
}): Promise<MarketplacePkg[]> {
|
||||
async getUpdates(
|
||||
localPkgs: Record<string, PackageDataEntry>,
|
||||
): Promise<MarketplacePkg[]> {
|
||||
const id = this.patch.getData().ui.marketplace?.['selected-id']
|
||||
const url = id
|
||||
? this.patch.getData().ui.marketplace['known-hosts'][id].url
|
||||
@@ -95,7 +95,7 @@ export class MarketplaceService {
|
||||
})
|
||||
}
|
||||
|
||||
async getPkg (id: string, version = '*'): Promise<MarketplacePkg> {
|
||||
async getPkg(id: string, version = '*'): Promise<MarketplacePkg> {
|
||||
const pkgs = await this.getMarketplacePkgs({
|
||||
ids: [{ id, version }],
|
||||
})
|
||||
@@ -108,11 +108,11 @@ export class MarketplaceService {
|
||||
}
|
||||
}
|
||||
|
||||
async cacheReleaseNotes (id: string): Promise<void> {
|
||||
async cacheReleaseNotes(id: string): Promise<void> {
|
||||
this.releaseNotes[id] = await this.getReleaseNotes({ id })
|
||||
}
|
||||
|
||||
async getMarketplaceData (
|
||||
async getMarketplaceData(
|
||||
params: RR.GetMarketplaceDataReq,
|
||||
url?: string,
|
||||
): Promise<RR.GetMarketplaceDataRes> {
|
||||
@@ -120,7 +120,7 @@ export class MarketplaceService {
|
||||
return this.api.marketplaceProxy('/package/v0/info', params, url)
|
||||
}
|
||||
|
||||
async getMarketplacePkgs (
|
||||
async getMarketplacePkgs(
|
||||
params: Omit<RR.GetMarketplacePackagesReq, 'eos-version-compat'>,
|
||||
): Promise<RR.GetMarketplacePackagesRes> {
|
||||
if (params.query) delete params.category
|
||||
@@ -139,7 +139,7 @@ export class MarketplaceService {
|
||||
)
|
||||
}
|
||||
|
||||
async getReleaseNotes (
|
||||
async getReleaseNotes(
|
||||
params: RR.GetReleaseNotesReq,
|
||||
): Promise<RR.GetReleaseNotesRes> {
|
||||
return this.api.marketplaceProxy(
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core'
|
||||
import { InstallProgress, packageLoadingProgress } from '@start9labs/shared'
|
||||
|
||||
@Pipe({
|
||||
name: 'installProgress',
|
||||
})
|
||||
export class InstallProgressPipe implements PipeTransform {
|
||||
transform(loadData: InstallProgress): string {
|
||||
const { totalProgress } = packageLoadingProgress(loadData)
|
||||
|
||||
return totalProgress < 99 ? totalProgress + '%' : 'finalizing'
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { NgModule } from '@angular/core'
|
||||
import { InstallProgressPipe } from './install-progress.pipe'
|
||||
import { TrustPipe } from './trust.pipe'
|
||||
|
||||
@NgModule({
|
||||
declarations: [InstallProgressPipe, TrustPipe],
|
||||
exports: [InstallProgressPipe, TrustPipe],
|
||||
})
|
||||
export class MarketplacePipesModule {}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core'
|
||||
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser'
|
||||
|
||||
@Pipe({
|
||||
name: 'trust',
|
||||
})
|
||||
export class TrustPipe implements PipeTransform {
|
||||
constructor(public readonly sanitizer: DomSanitizer) {}
|
||||
|
||||
transform(base64Icon: string): SafeResourceUrl {
|
||||
return this.sanitizer.bypassSecurityTrustResourceUrl(base64Icon)
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import { IonicModule } from '@ionic/angular'
|
||||
import { RouterModule, Routes } from '@angular/router'
|
||||
import { NotificationsPage } from './notifications.page'
|
||||
import { BadgeMenuComponentModule } from 'src/app/components/badge-menu-button/badge-menu.component.module'
|
||||
import { SharingModule } from 'src/app/modules/sharing.module'
|
||||
import { SharedPipesModule } from '@start9labs/shared'
|
||||
import { BackupReportPageModule } from 'src/app/modals/backup-report/backup-report.module'
|
||||
|
||||
const routes: Routes = [
|
||||
@@ -20,9 +20,9 @@ const routes: Routes = [
|
||||
IonicModule,
|
||||
RouterModule.forChild(routes),
|
||||
BadgeMenuComponentModule,
|
||||
SharingModule,
|
||||
SharedPipesModule,
|
||||
BackupReportPageModule,
|
||||
],
|
||||
declarations: [NotificationsPage],
|
||||
})
|
||||
export class NotificationsPageModule { }
|
||||
export class NotificationsPageModule {}
|
||||
|
||||
@@ -78,14 +78,10 @@
|
||||
<span *ngIf="not['package-id']"
|
||||
>{{ not['package-id'] }} -
|
||||
</span>
|
||||
<ion-text [color]="not | notificationColor"
|
||||
>{{ not.title }}</ion-text
|
||||
>
|
||||
<ion-text [color]="getColor(not)"> {{ not.title }} </ion-text>
|
||||
</b>
|
||||
</h2>
|
||||
<h2 class="notification-message">
|
||||
{{ not.message | truncateTail: 240 }}
|
||||
</h2>
|
||||
<h2 class="notification-message">{{ truncate(not.message) }}</h2>
|
||||
<p class="view-message-tag">
|
||||
<a
|
||||
class="view-message-tag"
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
import { Component } from '@angular/core'
|
||||
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||
import { ServerNotification, ServerNotifications } from 'src/app/services/api/api.types'
|
||||
import { AlertController, LoadingController, ModalController } from '@ionic/angular'
|
||||
import {
|
||||
ServerNotifications,
|
||||
NotificationLevel,
|
||||
ServerNotification,
|
||||
} from 'src/app/services/api/api.types'
|
||||
import {
|
||||
AlertController,
|
||||
LoadingController,
|
||||
ModalController,
|
||||
} from '@ionic/angular'
|
||||
import { ActivatedRoute } from '@angular/router'
|
||||
import { ErrorToastService } from 'src/app/services/error-toast.service'
|
||||
import { BackupReportPage } from 'src/app/modals/backup-report/backup-report.page'
|
||||
@@ -19,31 +27,34 @@ export class NotificationsPage {
|
||||
fromToast = false
|
||||
readonly perPage = 40
|
||||
|
||||
constructor (
|
||||
constructor(
|
||||
private readonly embassyApi: ApiService,
|
||||
private readonly alertCtrl: AlertController,
|
||||
private readonly loadingCtrl: LoadingController,
|
||||
private readonly modalCtrl: ModalController,
|
||||
private readonly errToast: ErrorToastService,
|
||||
private readonly route: ActivatedRoute,
|
||||
) { }
|
||||
) {}
|
||||
|
||||
async ngOnInit () {
|
||||
async ngOnInit() {
|
||||
this.fromToast = !!this.route.snapshot.queryParamMap.get('toast')
|
||||
this.notifications = await this.getNotifications()
|
||||
this.loading = false
|
||||
}
|
||||
|
||||
async doInfinite (e: any) {
|
||||
async doInfinite(e: any) {
|
||||
const notifications = await this.getNotifications()
|
||||
this.notifications = this.notifications.concat(notifications)
|
||||
e.target.complete()
|
||||
}
|
||||
|
||||
async getNotifications (): Promise<ServerNotifications> {
|
||||
async getNotifications(): Promise<ServerNotifications> {
|
||||
let notifications: ServerNotifications = []
|
||||
try {
|
||||
notifications = await this.embassyApi.getNotifications({ before: this.beforeCursor, limit: this.perPage })
|
||||
notifications = await this.embassyApi.getNotifications({
|
||||
before: this.beforeCursor,
|
||||
limit: this.perPage,
|
||||
})
|
||||
this.beforeCursor = notifications[notifications.length - 1]?.id
|
||||
this.needInfinite = notifications.length >= this.perPage
|
||||
} catch (e) {
|
||||
@@ -53,7 +64,7 @@ export class NotificationsPage {
|
||||
}
|
||||
}
|
||||
|
||||
async delete (id: number, index: number): Promise<void> {
|
||||
async delete(id: number, index: number): Promise<void> {
|
||||
const loader = await this.loadingCtrl.create({
|
||||
spinner: 'lines',
|
||||
message: 'Deleting...',
|
||||
@@ -72,7 +83,7 @@ export class NotificationsPage {
|
||||
}
|
||||
}
|
||||
|
||||
async presentAlertDeleteAll () {
|
||||
async presentAlertDeleteAll() {
|
||||
const alert = await this.alertCtrl.create({
|
||||
backdropDismiss: false,
|
||||
header: 'Delete All?',
|
||||
@@ -94,7 +105,7 @@ export class NotificationsPage {
|
||||
await alert.present()
|
||||
}
|
||||
|
||||
async viewBackupReport (notification: ServerNotification<1>) {
|
||||
async viewBackupReport(notification: ServerNotification<1>) {
|
||||
const modal = await this.modalCtrl.create({
|
||||
component: BackupReportPage,
|
||||
componentProps: {
|
||||
@@ -105,7 +116,7 @@ export class NotificationsPage {
|
||||
await modal.present()
|
||||
}
|
||||
|
||||
async viewFullMessage (title: string, message: string) {
|
||||
async viewFullMessage(title: string, message: string) {
|
||||
const alert = await this.alertCtrl.create({
|
||||
header: title,
|
||||
message: message,
|
||||
@@ -123,7 +134,26 @@ export class NotificationsPage {
|
||||
await alert.present()
|
||||
}
|
||||
|
||||
private async deleteAll (): Promise<void> {
|
||||
truncate(message: string): string {
|
||||
return message.length <= 240 ? message : '...' + message.substr(-240)
|
||||
}
|
||||
|
||||
getColor({ level }: ServerNotification<number>): string {
|
||||
switch (level) {
|
||||
case NotificationLevel.Info:
|
||||
return 'primary'
|
||||
case NotificationLevel.Success:
|
||||
return 'success'
|
||||
case NotificationLevel.Warning:
|
||||
return 'warning'
|
||||
case NotificationLevel.Error:
|
||||
return 'danger'
|
||||
default:
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
private async deleteAll(): Promise<void> {
|
||||
const loader = await this.loadingCtrl.create({
|
||||
spinner: 'lines',
|
||||
message: 'Deleting...',
|
||||
@@ -132,7 +162,9 @@ export class NotificationsPage {
|
||||
await loader.present()
|
||||
|
||||
try {
|
||||
await this.embassyApi.deleteAllNotifications({ before: this.notifications[0].id })
|
||||
await this.embassyApi.deleteAllNotifications({
|
||||
before: this.notifications[0].id,
|
||||
})
|
||||
this.notifications = []
|
||||
this.beforeCursor = undefined
|
||||
} catch (e) {
|
||||
@@ -142,4 +174,3 @@ export class NotificationsPage {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common'
|
||||
import { Routes, RouterModule } from '@angular/router'
|
||||
import { IonicModule } from '@ionic/angular'
|
||||
import { LANPage } from './lan.page'
|
||||
import { SharingModule } from 'src/app/modules/sharing.module'
|
||||
import { SharedPipesModule } from '@start9labs/shared'
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
@@ -17,8 +17,8 @@ const routes: Routes = [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
RouterModule.forChild(routes),
|
||||
SharingModule,
|
||||
SharedPipesModule,
|
||||
],
|
||||
declarations: [LANPage],
|
||||
})
|
||||
export class LANPageModule { }
|
||||
export class LANPageModule {}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common'
|
||||
import { IonicModule } from '@ionic/angular'
|
||||
import { RouterModule, Routes } from '@angular/router'
|
||||
import { MarketplacesPage } from './marketplaces.page'
|
||||
import { SharingModule } from 'src/app/modules/sharing.module'
|
||||
import { SharedPipesModule } from '@start9labs/shared'
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
@@ -17,7 +17,7 @@ const routes: Routes = [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
RouterModule.forChild(routes),
|
||||
SharingModule,
|
||||
SharedPipesModule,
|
||||
],
|
||||
declarations: [MarketplacesPage],
|
||||
})
|
||||
|
||||
@@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common'
|
||||
import { IonicModule } from '@ionic/angular'
|
||||
import { PreferencesPage } from './preferences.page'
|
||||
import { Routes, RouterModule } from '@angular/router'
|
||||
import { SharingModule } from 'src/app/modules/sharing.module'
|
||||
import { SharedPipesModule } from '@start9labs/shared'
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
@@ -17,10 +17,8 @@ const routes: Routes = [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
RouterModule.forChild(routes),
|
||||
SharingModule,
|
||||
],
|
||||
declarations: [
|
||||
PreferencesPage,
|
||||
SharedPipesModule,
|
||||
],
|
||||
declarations: [PreferencesPage],
|
||||
})
|
||||
export class PreferencesPageModule { }
|
||||
export class PreferencesPageModule {}
|
||||
|
||||
@@ -24,7 +24,7 @@ export class PreferencesPage {
|
||||
defaultName: string
|
||||
clicks = 0
|
||||
|
||||
constructor(
|
||||
constructor (
|
||||
private readonly loadingCtrl: LoadingController,
|
||||
private readonly modalCtrl: ModalController,
|
||||
private readonly api: ApiService,
|
||||
@@ -32,17 +32,17 @@ export class PreferencesPage {
|
||||
private readonly localStorageService: LocalStorageService,
|
||||
public readonly serverConfig: ServerConfigService,
|
||||
public readonly patch: PatchDbService,
|
||||
) {}
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
ngOnInit () {
|
||||
this.defaultName = `Embassy-${this.patch.getData()['server-info'].id}`
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
ngAfterViewInit () {
|
||||
this.content.scrollToPoint(undefined, 1)
|
||||
}
|
||||
|
||||
async presentModalName(): Promise<void> {
|
||||
async presentModalName (): Promise<void> {
|
||||
const options: GenericInputOptions = {
|
||||
title: 'Edit Device Name',
|
||||
message: 'This is for your reference only.',
|
||||
@@ -66,7 +66,7 @@ export class PreferencesPage {
|
||||
await modal.present()
|
||||
}
|
||||
|
||||
async setDbValue(key: string, value: any): Promise<void> {
|
||||
private async setDbValue (key: string, value: string): Promise<void> {
|
||||
const loader = await this.loadingCtrl.create({
|
||||
spinner: 'lines',
|
||||
message: 'Saving...',
|
||||
@@ -81,7 +81,7 @@ export class PreferencesPage {
|
||||
}
|
||||
}
|
||||
|
||||
async addClick() {
|
||||
async addClick () {
|
||||
this.clicks++
|
||||
if (this.clicks >= 5) {
|
||||
this.clicks = 0
|
||||
|
||||
@@ -3,7 +3,7 @@ import { RouterModule, Routes } from '@angular/router'
|
||||
import { CommonModule } from '@angular/common'
|
||||
import { IonicModule } from '@ionic/angular'
|
||||
import { RestorePage } from './restore.component'
|
||||
import { SharingModule } from 'src/app/modules/sharing.module'
|
||||
import { SharedPipesModule } from '@start9labs/shared'
|
||||
import { BackupDrivesComponentModule } from 'src/app/components/backup-drives/backup-drives.component.module'
|
||||
import { AppRecoverSelectPageModule } from 'src/app/modals/app-recover-select/app-recover-select.module'
|
||||
|
||||
@@ -19,12 +19,10 @@ const routes: Routes = [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
RouterModule.forChild(routes),
|
||||
SharingModule,
|
||||
SharedPipesModule,
|
||||
BackupDrivesComponentModule,
|
||||
AppRecoverSelectPageModule,
|
||||
],
|
||||
declarations: [
|
||||
RestorePage,
|
||||
],
|
||||
declarations: [RestorePage],
|
||||
})
|
||||
export class RestorePageModule { }
|
||||
export class RestorePageModule {}
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
import { Component } from '@angular/core'
|
||||
import { ModalController, NavController } from '@ionic/angular'
|
||||
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||
import { GenericInputComponent, GenericInputOptions } from 'src/app/modals/generic-input/generic-input.component'
|
||||
import { MappedBackupTarget } from 'src/app/util/misc.util'
|
||||
import { BackupInfo, CifsBackupTarget, DiskBackupTarget } from 'src/app/services/api/api.types'
|
||||
import {
|
||||
GenericInputComponent,
|
||||
GenericInputOptions,
|
||||
} from 'src/app/modals/generic-input/generic-input.component'
|
||||
import { MappedBackupTarget } from 'src/app/types/mapped-backup-target'
|
||||
import {
|
||||
BackupInfo,
|
||||
CifsBackupTarget,
|
||||
DiskBackupTarget,
|
||||
} from 'src/app/services/api/api.types'
|
||||
import { AppRecoverSelectPage } from 'src/app/modals/app-recover-select/app-recover-select.page'
|
||||
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
||||
import * as argon2 from '@start9labs/argon2'
|
||||
@@ -14,18 +21,20 @@ import * as argon2 from '@start9labs/argon2'
|
||||
styleUrls: ['./restore.component.scss'],
|
||||
})
|
||||
export class RestorePage {
|
||||
|
||||
constructor (
|
||||
constructor(
|
||||
private readonly modalCtrl: ModalController,
|
||||
private readonly navCtrl: NavController,
|
||||
private readonly embassyApi: ApiService,
|
||||
private readonly patch: PatchDbService,
|
||||
) { }
|
||||
) {}
|
||||
|
||||
async presentModalPassword (target: MappedBackupTarget<CifsBackupTarget | DiskBackupTarget>): Promise<void> {
|
||||
async presentModalPassword(
|
||||
target: MappedBackupTarget<CifsBackupTarget | DiskBackupTarget>,
|
||||
): Promise<void> {
|
||||
const options: GenericInputOptions = {
|
||||
title: 'Master Password Required',
|
||||
message: 'Enter your master password. On the next screen, you will select the individual services you want to restore.',
|
||||
message:
|
||||
'Enter your master password. On the next screen, you will select the individual services you want to restore.',
|
||||
label: 'Master Password',
|
||||
placeholder: 'Enter master password',
|
||||
useMask: true,
|
||||
@@ -43,7 +52,10 @@ export class RestorePage {
|
||||
await modal.present()
|
||||
}
|
||||
|
||||
private async decryptDrive (target: MappedBackupTarget<CifsBackupTarget | DiskBackupTarget>, password: string): Promise<void> {
|
||||
private async decryptDrive(
|
||||
target: MappedBackupTarget<CifsBackupTarget | DiskBackupTarget>,
|
||||
password: string,
|
||||
): Promise<void> {
|
||||
const passwordHash = this.patch.getData()['server-info']['password-hash']
|
||||
argon2.verify(passwordHash, password)
|
||||
|
||||
@@ -55,15 +67,20 @@ export class RestorePage {
|
||||
}
|
||||
}
|
||||
|
||||
private async presentModalOldPassword (target: MappedBackupTarget<CifsBackupTarget | DiskBackupTarget>, password: string): Promise<void> {
|
||||
private async presentModalOldPassword(
|
||||
target: MappedBackupTarget<CifsBackupTarget | DiskBackupTarget>,
|
||||
password: string,
|
||||
): Promise<void> {
|
||||
const options: GenericInputOptions = {
|
||||
title: 'Original Password Needed',
|
||||
message: 'This backup was created with a different password. Enter the ORIGINAL password that was used to encrypt this backup.',
|
||||
message:
|
||||
'This backup was created with a different password. Enter the ORIGINAL password that was used to encrypt this backup.',
|
||||
label: 'Original Password',
|
||||
placeholder: 'Enter original password',
|
||||
useMask: true,
|
||||
buttonText: 'Restore From Backup',
|
||||
submitFn: (oldPassword: string) => this.restoreFromBackup(target, password, oldPassword),
|
||||
submitFn: (oldPassword: string) =>
|
||||
this.restoreFromBackup(target, password, oldPassword),
|
||||
}
|
||||
|
||||
const m = await this.modalCtrl.create({
|
||||
@@ -76,7 +93,11 @@ export class RestorePage {
|
||||
await m.present()
|
||||
}
|
||||
|
||||
private async restoreFromBackup (target: MappedBackupTarget<CifsBackupTarget | DiskBackupTarget>, password: string, oldPassword?: string): Promise<void> {
|
||||
private async restoreFromBackup(
|
||||
target: MappedBackupTarget<CifsBackupTarget | DiskBackupTarget>,
|
||||
password: string,
|
||||
oldPassword?: string,
|
||||
): Promise<void> {
|
||||
const backupInfo = await this.embassyApi.getBackupInfo({
|
||||
'target-id': target.id,
|
||||
password,
|
||||
@@ -84,7 +105,12 @@ export class RestorePage {
|
||||
this.presentModalSelect(target.id, backupInfo, password, oldPassword)
|
||||
}
|
||||
|
||||
private async presentModalSelect (id: string, backupInfo: BackupInfo, password: string, oldPassword?: string): Promise<void> {
|
||||
private async presentModalSelect(
|
||||
id: string,
|
||||
backupInfo: BackupInfo,
|
||||
password: string,
|
||||
oldPassword?: string,
|
||||
): Promise<void> {
|
||||
const modal = await this.modalCtrl.create({
|
||||
componentProps: {
|
||||
id,
|
||||
|
||||
@@ -4,7 +4,7 @@ import { IonicModule } from '@ionic/angular'
|
||||
import { ServerBackupPage } from './server-backup.page'
|
||||
import { RouterModule, Routes } from '@angular/router'
|
||||
import { BackupDrivesComponentModule } from 'src/app/components/backup-drives/backup-drives.component.module'
|
||||
import { SharingModule } from 'src/app/modules/sharing.module'
|
||||
import { SharedPipesModule } from '@start9labs/shared'
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
@@ -18,11 +18,9 @@ const routes: Routes = [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
RouterModule.forChild(routes),
|
||||
SharingModule,
|
||||
SharedPipesModule,
|
||||
BackupDrivesComponentModule,
|
||||
],
|
||||
declarations: [
|
||||
ServerBackupPage,
|
||||
],
|
||||
declarations: [ServerBackupPage],
|
||||
})
|
||||
export class ServerBackupPageModule { }
|
||||
export class ServerBackupPageModule {}
|
||||
|
||||
@@ -10,14 +10,13 @@ import {
|
||||
GenericInputOptions,
|
||||
} from 'src/app/modals/generic-input/generic-input.component'
|
||||
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
||||
import { Subscription } from 'rxjs'
|
||||
import { take } from 'rxjs/operators'
|
||||
import { MappedBackupTarget } from 'src/app/types/mapped-backup-target'
|
||||
import {
|
||||
PackageDataEntry,
|
||||
PackageMainStatus,
|
||||
ServerStatus,
|
||||
} from 'src/app/services/patch-db/data-model'
|
||||
import { Subscription } from 'rxjs'
|
||||
import { take } from 'rxjs/operators'
|
||||
import { MappedBackupTarget } from 'src/app/util/misc.util'
|
||||
import * as argon2 from '@start9labs/argon2'
|
||||
import {
|
||||
CifsBackupTarget,
|
||||
|
||||
@@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common'
|
||||
import { Routes, RouterModule } from '@angular/router'
|
||||
import { IonicModule } from '@ionic/angular'
|
||||
import { ServerLogsPage } from './server-logs.page'
|
||||
import { SharingModule } from 'src/app/modules/sharing.module'
|
||||
import { SharedPipesModule } from '@start9labs/shared'
|
||||
import { LogsPageModule } from 'src/app/components/logs/logs.module'
|
||||
|
||||
const routes: Routes = [
|
||||
@@ -18,9 +18,9 @@ const routes: Routes = [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
RouterModule.forChild(routes),
|
||||
SharingModule,
|
||||
SharedPipesModule,
|
||||
LogsPageModule,
|
||||
],
|
||||
declarations: [ServerLogsPage],
|
||||
})
|
||||
export class ServerLogsPageModule { }
|
||||
export class ServerLogsPageModule {}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Routes, RouterModule } from '@angular/router'
|
||||
import { IonicModule } from '@ionic/angular'
|
||||
import { ServerMetricsPage } from './server-metrics.page'
|
||||
import { SkeletonListComponentModule } from 'src/app/components/skeleton-list/skeleton-list.component.module'
|
||||
import { SharingModule } from 'src/app/modules/sharing.module'
|
||||
import { SharedPipesModule } from '@start9labs/shared'
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
@@ -19,8 +19,8 @@ const routes: Routes = [
|
||||
IonicModule,
|
||||
RouterModule.forChild(routes),
|
||||
SkeletonListComponentModule,
|
||||
SharingModule,
|
||||
SharedPipesModule,
|
||||
],
|
||||
declarations: [ServerMetricsPage],
|
||||
})
|
||||
export class ServerMetricsPageModule { }
|
||||
export class ServerMetricsPageModule {}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Component } from '@angular/core'
|
||||
import { Metrics } from 'src/app/services/api/api.types'
|
||||
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||
import { ErrorToastService } from 'src/app/services/error-toast.service'
|
||||
import { pauseFor } from 'src/app/util/misc.util'
|
||||
import { pauseFor } from '@start9labs/shared'
|
||||
|
||||
@Component({
|
||||
selector: 'server-metrics',
|
||||
@@ -12,14 +12,14 @@ import { pauseFor } from 'src/app/util/misc.util'
|
||||
export class ServerMetricsPage {
|
||||
loading = true
|
||||
going = false
|
||||
metrics: Metrics = { }
|
||||
metrics: Metrics = {}
|
||||
|
||||
constructor (
|
||||
constructor(
|
||||
private readonly errToast: ErrorToastService,
|
||||
private readonly embassyApi: ApiService,
|
||||
) { }
|
||||
) {}
|
||||
|
||||
async ngOnInit () {
|
||||
async ngOnInit() {
|
||||
await this.getMetrics()
|
||||
let headersCount = 0
|
||||
let rowsCount = 0
|
||||
@@ -36,11 +36,11 @@ export class ServerMetricsPage {
|
||||
this.loading = false
|
||||
}
|
||||
|
||||
ngOnDestroy () {
|
||||
ngOnDestroy() {
|
||||
this.stopDaemon()
|
||||
}
|
||||
|
||||
private async startDaemon (): Promise<void> {
|
||||
private async startDaemon(): Promise<void> {
|
||||
this.going = true
|
||||
while (this.going) {
|
||||
const startTime = Date.now()
|
||||
@@ -49,20 +49,20 @@ export class ServerMetricsPage {
|
||||
}
|
||||
}
|
||||
|
||||
private stopDaemon () {
|
||||
private stopDaemon() {
|
||||
this.going = false
|
||||
}
|
||||
|
||||
private async getMetrics (): Promise<void> {
|
||||
private async getMetrics(): Promise<void> {
|
||||
try {
|
||||
this.metrics = await this.embassyApi.getServerMetrics({ })
|
||||
this.metrics = await this.embassyApi.getServerMetrics({})
|
||||
} catch (e) {
|
||||
this.errToast.present(e)
|
||||
this.stopDaemon()
|
||||
}
|
||||
}
|
||||
|
||||
asIsOrder (a: any, b: any) {
|
||||
asIsOrder(a: any, b: any) {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,9 +3,8 @@ import { CommonModule } from '@angular/common'
|
||||
import { IonicModule } from '@ionic/angular'
|
||||
import { RouterModule, Routes } from '@angular/router'
|
||||
import { ServerShowPage } from './server-show.page'
|
||||
import { StatusComponentModule } from 'src/app/components/status/status.component.module'
|
||||
import { FormsModule } from '@angular/forms'
|
||||
import { SharingModule } from 'src/app/modules/sharing.module'
|
||||
import { TextSpinnerComponentModule } from '@start9labs/shared'
|
||||
import { BadgeMenuComponentModule } from 'src/app/components/badge-menu-button/badge-menu.component.module'
|
||||
|
||||
const routes: Routes = [
|
||||
@@ -19,12 +18,11 @@ const routes: Routes = [
|
||||
imports: [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
StatusComponentModule,
|
||||
IonicModule,
|
||||
RouterModule.forChild(routes),
|
||||
SharingModule,
|
||||
TextSpinnerComponentModule,
|
||||
BadgeMenuComponentModule,
|
||||
],
|
||||
declarations: [ServerShowPage],
|
||||
})
|
||||
export class ServerShowPageModule { }
|
||||
export class ServerShowPageModule {}
|
||||
|
||||
@@ -10,13 +10,13 @@ import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||
import { ActivatedRoute } from '@angular/router'
|
||||
import { ErrorToastService } from 'src/app/services/error-toast.service'
|
||||
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
||||
import { ServerStatus } from 'src/app/services/patch-db/data-model'
|
||||
import { Observable, of } from 'rxjs'
|
||||
import { filter, map, take } from 'rxjs/operators'
|
||||
import { WizardBaker } from 'src/app/components/install-wizard/prebaked-wizards'
|
||||
import { wizardModal } from 'src/app/components/install-wizard/install-wizard.component'
|
||||
import { exists, isEmptyObject } from 'src/app/util/misc.util'
|
||||
import { exists, isEmptyObject } from '@start9labs/shared'
|
||||
import { EOSService } from 'src/app/services/eos.service'
|
||||
import { ServerStatus } from 'src/app/services/patch-db/data-model'
|
||||
|
||||
@Component({
|
||||
selector: 'server-show',
|
||||
|
||||
@@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common'
|
||||
import { Routes, RouterModule } from '@angular/router'
|
||||
import { IonicModule } from '@ionic/angular'
|
||||
import { ServerSpecsPage } from './server-specs.page'
|
||||
import { SharingModule } from 'src/app/modules/sharing.module'
|
||||
import { EmverPipesModule } from '@start9labs/shared'
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
@@ -17,8 +17,8 @@ const routes: Routes = [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
RouterModule.forChild(routes),
|
||||
SharingModule,
|
||||
EmverPipesModule,
|
||||
],
|
||||
declarations: [ServerSpecsPage],
|
||||
})
|
||||
export class ServerSpecsPageModule { }
|
||||
export class ServerSpecsPageModule {}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common'
|
||||
import { IonicModule } from '@ionic/angular'
|
||||
import { RouterModule, Routes } from '@angular/router'
|
||||
import { SessionsPage } from './sessions.page'
|
||||
import { SharingModule } from 'src/app/modules/sharing.module'
|
||||
import { SharedPipesModule } from '@start9labs/shared'
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
@@ -17,8 +17,8 @@ const routes: Routes = [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
RouterModule.forChild(routes),
|
||||
SharingModule,
|
||||
SharedPipesModule,
|
||||
],
|
||||
declarations: [SessionsPage],
|
||||
})
|
||||
export class SessionsPageModule { }
|
||||
export class SessionsPageModule {}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common'
|
||||
import { IonicModule } from '@ionic/angular'
|
||||
import { RouterModule, Routes } from '@angular/router'
|
||||
import { SSHKeysPage } from './ssh-keys.page'
|
||||
import { SharingModule } from 'src/app/modules/sharing.module'
|
||||
import { SharedPipesModule } from '@start9labs/shared'
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
@@ -17,8 +17,8 @@ const routes: Routes = [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
RouterModule.forChild(routes),
|
||||
SharingModule,
|
||||
SharedPipesModule,
|
||||
],
|
||||
declarations: [SSHKeysPage],
|
||||
})
|
||||
export class SSHKeysPageModule { }
|
||||
export class SSHKeysPageModule {}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common'
|
||||
import { IonicModule } from '@ionic/angular'
|
||||
import { RouterModule, Routes } from '@angular/router'
|
||||
import { WifiPage } from './wifi.page'
|
||||
import { SharingModule } from 'src/app/modules/sharing.module'
|
||||
import { SharedPipesModule } from '@start9labs/shared'
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
@@ -17,8 +17,8 @@ const routes: Routes = [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
RouterModule.forChild(routes),
|
||||
SharingModule,
|
||||
SharedPipesModule,
|
||||
],
|
||||
declarations: [WifiPage],
|
||||
})
|
||||
export class WifiPageModule { }
|
||||
export class WifiPageModule {}
|
||||
|
||||
@@ -12,7 +12,7 @@ import { ActionSheetButton } from '@ionic/core'
|
||||
import { ErrorToastService } from 'src/app/services/error-toast.service'
|
||||
import { ValueSpecObject } from 'src/app/pkg-config/config-types'
|
||||
import { RR } from 'src/app/services/api/api.types'
|
||||
import { pauseFor } from 'src/app/util/misc.util'
|
||||
import { pauseFor } from '@start9labs/shared'
|
||||
import { GenericFormPage } from 'src/app/modals/generic-form/generic-form.page'
|
||||
import { ConfigService } from 'src/app/services/config.service'
|
||||
|
||||
|
||||
Reference in New Issue
Block a user