UI/feature/actions (#195)

* ui: actions page

* rework actions page

* add warning to Actions

Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
This commit is contained in:
Aaron Greenspan
2021-02-15 10:25:01 -07:00
committed by Aiden McClelland
parent 5cf7d1ff88
commit 02ab63da81
17 changed files with 272 additions and 28 deletions

View File

@@ -1,5 +1,5 @@
import { Rules } from '../../models/app-model'
import { AppAvailablePreview, AppAvailableFull, AppInstalledPreview, AppInstalledFull, DependentBreakage, AppAvailableVersionSpecificInfo } from '../../models/app-types'
import { AppAvailablePreview, AppAvailableFull, AppInstalledPreview, AppInstalledFull, DependentBreakage, AppAvailableVersionSpecificInfo, ServiceAction } from '../../models/app-types'
import { S9Notification, SSHFingerprint, ServerMetrics, DiskInfo } from '../../models/server-model'
import { Subject, Observable } from 'rxjs'
import { Unit, ApiServer, ApiAppInstalledFull, ApiAppConfig, ApiAppAvailableFull } from './api-types'
@@ -51,7 +51,7 @@ export abstract class ApiService {
abstract restoreAppBackup (appId: string, logicalname: string, password?: string): Promise<Unit>
abstract stopAppBackup (appId: string): Promise<Unit>
abstract patchAppConfig (app: AppInstalledPreview, config: object, dryRun?: boolean): Promise<{ breakages: DependentBreakage[] }>
abstract postConfigureDependency (dependencyId: string, dependentId: string, dryRun?: boolean): Promise< {config: object, breakages: DependentBreakage[] }>
abstract postConfigureDependency (dependencyId: string, dependentId: string, dryRun?: boolean): Promise< { config: object, breakages: DependentBreakage[] }>
abstract patchServerConfig (attr: string, value: any): Promise<Unit>
abstract wipeAppData (app: AppInstalledPreview): Promise<Unit>
abstract addSSHKey (sshKey: string): Promise<Unit>
@@ -62,12 +62,30 @@ export abstract class ApiService {
abstract restartServer (): Promise<Unit>
abstract shutdownServer (): Promise<Unit>
abstract ejectExternalDisk (logicalName: string): Promise<Unit>
abstract serviceAction (appId: string, serviceAction: ServiceAction): Promise<ReqRes.ServiceActionResponse>
}
export function isRpcFailure<Error, Result> (arg: { error: Error } | { result: Result}): arg is { error: Error } {
return !!(arg as any).error
}
export function isRpcSuccess<Error, Result> (arg: { error: Error } | { result: Result}): arg is { result: Result } {
return !!(arg as any).result
}
export module ReqRes {
export type GetVersionRes = { version: string }
export type PostLoginReq = { password: string }
export type PostLoginRes = Unit
export type ServiceActionRequest = {
jsonrpc: '2.0',
id: string,
method: string
}
export type ServiceActionResponse = {
jsonrpc: '2.0',
id: string
} & ({ error: { code: number, message: string } } | { result : string })
export type GetCheckAuthRes = { }
export type GetServerRes = ApiServer
export type GetVersionLatestRes = { versionLatest: string, releaseNotes: string }

View File

@@ -1,7 +1,7 @@
import { Injectable } from '@angular/core'
import { HttpService, Method, HttpOptions } from '../http.service'
import { AppModel, AppStatus } from '../../models/app-model'
import { AppAvailablePreview, AppAvailableFull, AppInstalledFull, AppInstalledPreview, DependentBreakage, AppAvailableVersionSpecificInfo } from '../../models/app-types'
import { AppAvailablePreview, AppAvailableFull, AppInstalledFull, AppInstalledPreview, DependentBreakage, AppAvailableVersionSpecificInfo, ServiceAction } from '../../models/app-types'
import { S9Notification, SSHFingerprint, ServerModel, DiskInfo } from '../../models/server-model'
import { ApiService, ReqRes } from './api.service'
import { ApiServer, Unit } from './api-types'
@@ -12,6 +12,7 @@ import { AppMetrics, parseMetricsPermissive } from 'src/app/util/metrics.util'
import { modulateTime } from 'src/app/util/misc.util'
import { Observable, of, throwError } from 'rxjs'
import { catchError, mapTo } from 'rxjs/operators'
import * as uuid from 'uuid'
@Injectable()
export class LiveApiService extends ApiService {
@@ -266,6 +267,15 @@ export class LiveApiService extends ApiService {
return this.authRequest({ method: Method.POST, url: '/shutdown', readTimeout: 60000 })
}
async serviceAction (appId: string, s: ServiceAction): Promise<ReqRes.ServiceActionResponse> {
const data: ReqRes.ServiceActionRequest = {
jsonrpc: '2.0',
id: uuid.v4(),
method: s.id,
}
return this.authRequest({ method: Method.POST, url: `apps/${appId}/actions`, data })
}
private async authRequest<T> (opts: HttpOptions, overrides: Partial<{ version: string }> = { }): Promise<T> {
if (!this.authenticatedRequestsEnabled) throw new Error(`Authenticated requests are not enabled. Do you need to login?`)

View File

@@ -1,6 +1,6 @@
import { Injectable } from '@angular/core'
import { AppStatus, AppModel } from '../../models/app-model'
import { AppAvailablePreview, AppAvailableFull, AppInstalledPreview, AppInstalledFull, DependentBreakage, AppAvailableVersionSpecificInfo } from '../../models/app-types'
import { AppAvailablePreview, AppAvailableFull, AppInstalledPreview, AppInstalledFull, DependentBreakage, AppAvailableVersionSpecificInfo, ServiceAction } from '../../models/app-types'
import { S9Notification, SSHFingerprint, ServerStatus, ServerModel, DiskInfo } from '../../models/server-model'
import { pauseFor } from '../../util/misc.util'
import { ApiService, ReqRes } from './api.service'
@@ -228,6 +228,20 @@ export class MockApiService extends ApiService {
async shutdownServer (): Promise<EmptyResponse> {
return mockShutdownServer()
}
async serviceAction (appId: string, action: ServiceAction): Promise<ReqRes.ServiceActionResponse> {
console.log('service action', appId, action)
await pauseFor(1000)
return {
jsonrpc: '2.0',
id: '0',
// result: 'Congrats! you did ' + action.name,
error: {
code: 1,
message: 'woooo that was bad bad bad',
},
}
}
}
async function mockGetServer (): Promise<ReqRes.GetServerRes> {

View File

@@ -60,7 +60,11 @@ export const bitcoinI: AppInstalledFull = {
configuredRequirements: [],
hasFetchedFull: true,
ui: false,
restoreAlert: 'if you restore this app horrible things will happen to the people you love.'
restoreAlert: 'if you restore this app horrible things will happen to the people you love.',
actions: [
{ id: 'sync-chain', name: 'Sync Chain', description: 'this will sync with the chain like from Avatar', allowedStatuses: [ AppStatus.RUNNING, AppStatus.RUNNING, AppStatus.RUNNING, AppStatus.RUNNING ]},
{ id: 'off-sync-chain', name: 'Off Sync Chain', description: 'this will off sync with the chain like from Avatar', allowedStatuses: [ AppStatus.STOPPED ]}
],
}
export const lightningI: AppInstalledFull = {
@@ -86,6 +90,7 @@ export const lightningI: AppInstalledFull = {
],
hasFetchedFull: true,
ui: true,
actions: [],
}
export const cupsI: AppInstalledFull = {
@@ -132,6 +137,7 @@ export const cupsI: AppInstalledFull = {
}),
],
hasFetchedFull: true,
actions: [],
}
export const bitcoinA: AppAvailableFull = {