chore: cleanup - show spinner on service list when transitioning

config add new list items to end and auto scroll

remove js engine artifacts

fix view button in notification toast
This commit is contained in:
Matt Hill
2022-06-09 13:01:39 -06:00
committed by Lucy C
parent 7916a2352f
commit 8e9d2b5314
15 changed files with 87 additions and 49 deletions

2
.gitignore vendored
View File

@@ -9,3 +9,5 @@
/*_product_key.txt
.vscode/settings.json
deploy_web.sh
libs/js_engine/src/artifacts/ARM_JS_SNAPSHOT.bin
libs/js_engine/src/artifacts/JS_SNAPSHOT.bin

View File

@@ -5,7 +5,7 @@ import {
ToastController,
ToastOptions,
} from '@ionic/angular'
import { EMPTY, merge, Observable } from 'rxjs'
import { EMPTY, merge, Observable, ObservableInput } from 'rxjs'
import { filter, pairwise, switchMap, tap } from 'rxjs/operators'
import { ErrorToastService } from '@start9labs/shared'
@@ -13,6 +13,7 @@ import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
import { ConfigService } from 'src/app/services/config.service'
import { ApiService } from 'src/app/services/api/embassy-api.service'
import { PatchDataService } from './patch-data.service'
import { DataModel, ServerInfo } from 'src/app/services/patch-db/data-model'
// Watch unread notification count to display toast
@Injectable()
@@ -20,7 +21,7 @@ export class UnreadToastService extends Observable<unknown> {
private unreadToast: HTMLIonToastElement
private readonly stream$ = this.patchData.pipe(
switchMap(data => {
switchMap<DataModel | null, ObservableInput<number>>(data => {
if (data) {
return this.patch.watch$('server-info', 'unread-notification-count')
}
@@ -36,6 +37,29 @@ export class UnreadToastService extends Observable<unknown> {
}),
)
TOAST: ToastOptions = {
header: 'Embassy',
message: `New notifications`,
position: 'bottom',
duration: 4000,
buttons: [
{
side: 'start',
icon: 'close',
handler: () => true,
},
{
side: 'end',
text: 'View',
handler: () => {
this.router.navigate(['/notifications'], {
queryParams: { toast: true },
})
},
},
],
}
constructor(
private readonly router: Router,
private readonly patchData: PatchDataService,
@@ -50,31 +74,9 @@ export class UnreadToastService extends Observable<unknown> {
private async showToast() {
await this.unreadToast?.dismiss()
this.unreadToast = await this.toastCtrl.create(TOAST)
this.unreadToast.buttons?.push({
side: 'end',
text: 'View',
handler: () => {
this.router.navigate(['/notifications'], {
queryParams: { toast: true },
})
},
})
this.unreadToast = await this.toastCtrl.create(this.TOAST)
this.unreadToast.buttons?.push()
await this.unreadToast.present()
}
}
const TOAST: ToastOptions = {
header: 'Embassy',
message: `New notifications`,
position: 'bottom',
duration: 4000,
buttons: [
{
side: 'start',
icon: 'close',
handler: () => true,
},
],
}

View File

@@ -7,6 +7,7 @@ const ICONS = [
'alert-circle-outline',
'aperture-outline',
'arrow-back',
'arrow-forward',
'arrow-up',
'briefcase-outline',
'bookmark-outline',

View File

@@ -304,6 +304,7 @@
</ng-container>
<!-- string or number -->
<ion-item-group
[id]="getElementId(entry.key, i)"
*ngIf="spec.subtype === 'string' || spec.subtype === 'number'"
>
<ion-item color="dark">

View File

@@ -141,23 +141,25 @@ export class FormObjectComponent {
if (!newItem) return
const index = arr.length
newItem.markAllAsTouched()
arr.insert(0, newItem)
arr.insert(index, newItem)
if (['object', 'union'].includes(listSpec.subtype)) {
const displayAs = (listSpec.spec as ListValueSpecOf<'object'>)[
'display-as'
]
this.objectListDisplay[key].unshift({
this.objectListDisplay[key].push({
height: '0px',
expanded: true,
displayAs: displayAs ? Mustache.render(displayAs, newItem.value) : '',
})
pauseFor(200).then(() => {
this.objectListDisplay[key][0].height = this.getDocSize(key, 0)
this.onExpand.emit()
})
}
pauseFor(400).then(() => {
const element = document.getElementById(this.getElementId(key, index))
element?.parentElement?.scrollIntoView({ behavior: 'smooth' })
})
}
toggleExpandObject(key: string) {

View File

@@ -1,10 +1,18 @@
<ion-icon
*ngIf="pkg.error; else bulb"
*ngIf="pkg.error; else noError"
class="warning-icon"
name="warning-outline"
size="small"
color="warning"
></ion-icon>
<ng-template #bulb>
<div class="bulb" [style.background-color]="color"></div>
<ng-template #noError>
<ion-spinner
*ngIf="pkg.transitioning; else bulb"
class="spinner"
size="small"
color="primary"
></ion-spinner>
<ng-template #bulb>
<div class="bulb" [style.background-color]="color"></div>
</ng-template>
</ng-template>

View File

@@ -18,3 +18,10 @@
background-color: rgba(255, 213, 52, 0.1);
box-shadow: 0 0 4px 4px rgba(255, 213, 52, 0.1);
}
.spinner {
position: absolute !important;
left: 6px !important;
top: 6px !important;
width: 18px;
}

View File

@@ -1,5 +1,4 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
import { AlertController } from '@ionic/angular'
import {
HealthResult,
PackageDataEntry,
@@ -20,8 +19,6 @@ export class AppShowHealthChecksComponent {
HealthResult = HealthResult
constructor(private readonly alertCtrl: AlertController) {}
isLoading(result: HealthResult): boolean {
return result === HealthResult.Starting || result === HealthResult.Loading
}

View File

@@ -12,7 +12,10 @@ import { ValueSpecObject } from 'src/app/pkg-config/config-types'
import { GenericFormPage } from 'src/app/modals/generic-form/generic-form.page'
import { PatchDbService } from '../../../services/patch-db/patch-db.service'
import { v4 } from 'uuid'
import { UIMarketplaceData } from '../../../services/patch-db/data-model'
import {
UIData,
UIMarketplaceData,
} from '../../../services/patch-db/data-model'
import { ConfigService } from '../../../services/config.service'
import { MarketplaceService } from 'src/app/services/marketplace.service'
import {
@@ -54,10 +57,10 @@ export class MarketplacesPage {
this.patch
.watch$('ui')
.pipe(
map(ui => ui.marketplace),
map((ui: UIData) => ui.marketplace),
distinctUntilChanged(),
)
.subscribe(mp => {
.subscribe((mp: UIMarketplaceData | undefined) => {
let marketplaces: Marketplaces = [
{
id: undefined,

View File

@@ -12,6 +12,7 @@ import { ApiService } from 'src/app/services/api/embassy-api.service'
import { ConfigService } from 'src/app/services/config.service'
import {
ServerInfo,
UIData,
UIMarketplaceData,
} from 'src/app/services/patch-db/data-model'
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
@@ -34,7 +35,7 @@ export class MarketplaceService extends AbstractMarketplaceService {
private readonly altMarketplaceData$: Observable<
UIMarketplaceData | undefined
> = this.patch.watch$('ui').pipe(
map(ui => ui.marketplace),
map((ui: UIData) => ui.marketplace),
distinctUntilChanged(),
shareReplay({ bufferSize: 1, refCount: true }),
)

View File

@@ -16,11 +16,12 @@ export function renderPkgStatus(pkg: PackageDataEntry): PackageStatus {
let primary: PrimaryStatus
let dependency: DependencyStatus | null = null
let health: HealthStatus | null = null
const hasHealthChecks = !isEmptyObject(pkg.manifest['health-checks'])
if (pkg.state === PackageState.Installed && pkg.installed) {
primary = getPrimaryStatus(pkg.installed.status)
dependency = getDependencyStatus(pkg)
health = getHealthStatus(pkg.installed.status)
health = getHealthStatus(pkg.installed.status, hasHealthChecks)
} else {
primary = pkg.state as string as PrimaryStatus
}
@@ -56,19 +57,24 @@ function getHealthStatus(
}
const values = Object.values(status.main.health)
console.log('HEALTH CHECKS', values)
if (values.some(h => h.result === 'failure')) {
return HealthStatus.Failure
}
if (values.some(h => h.result === 'starting')) {
return HealthStatus.Starting
if (!values.length && hasHealthChecks) {
return HealthStatus.Waiting
}
if (values.some(h => h.result === 'loading')) {
return HealthStatus.Loading
}
if (values.some(h => !h.result || h.result === 'starting')) {
return HealthStatus.Starting
}
return HealthStatus.Healthy
}
@@ -101,6 +107,7 @@ export enum DependencyStatus {
export enum HealthStatus {
Failure = 'failure',
Waiting = 'waiting',
Starting = 'starting',
Loading = 'loading',
Healthy = 'healthy',

View File

@@ -12,14 +12,20 @@ import { packageLoadingProgress } from './package-loading-progress'
export function getPackageInfo(entry: PackageDataEntry): PkgInfo {
const statuses = renderPkgStatus(entry)
const primaryRendering = PrimaryRendering[statuses.primary]
return {
entry,
primaryRendering: PrimaryRendering[statuses.primary],
primaryRendering,
installProgress: packageLoadingProgress(entry['install-progress']),
error:
statuses.health === HealthStatus.Failure ||
statuses.dependency === DependencyStatus.Warning,
transitioning:
primaryRendering.showDots ||
statuses.health === HealthStatus.Waiting ||
statuses.health === HealthStatus.Loading ||
statuses.health === HealthStatus.Starting,
}
}
@@ -28,5 +34,6 @@ export interface PkgInfo {
primaryRendering: StatusRendering
installProgress: ProgressData | null
error: boolean
transitioning: boolean
sub?: Subscription | null
}

View File

@@ -2,7 +2,7 @@
"/rpc/v1": {
"target": "http://<CHANGE_ME>/rpc/v1"
},
"/ws/*": {
"/ws/db": {
"target": "http://<CHANGE_ME>",
"secure": false,
"ws": true