Feat/combine uis (#2633)

* wip

* restructure backend for new ui structure

* new patchdb bootstrap, single websocket api, local storage migration, more

* update db websocket

* init apis

* update patch-db

* setup progress

* feat: implement state service, alert and routing

Signed-off-by: waterplea <alexander@inkin.ru>

* update setup wizard for new types

* feat: add init page

Signed-off-by: waterplea <alexander@inkin.ru>

* chore: refactor message, patch-db source stream and connection service

Signed-off-by: waterplea <alexander@inkin.ru>

* fix method not found on state

* fix backend bugs

* fix compat assets

* address comments

* remove unneeded styling

* cleaner progress

* bugfixes

* fix init logs

* fix progress reporting

* fix navigation by getting state after init

* remove patch dependency from live api

* fix caching

* re-add patchDB to live api

* fix metrics values

* send close frame

* add bootId and fix polling

---------

Signed-off-by: waterplea <alexander@inkin.ru>
Co-authored-by: Aiden McClelland <me@drbonez.dev>
Co-authored-by: waterplea <alexander@inkin.ru>
This commit is contained in:
Matt Hill
2024-06-19 13:51:44 -06:00
committed by GitHub
parent e92d4ff147
commit da3720c7a9
147 changed files with 3939 additions and 2637 deletions

View File

@@ -0,0 +1,33 @@
import { Component, ElementRef, inject } from '@angular/core'
import { INTERSECTION_ROOT } from '@ng-web-apis/intersection-observer'
import { LogsService } from 'src/app/pages/init/logs/logs.service'
@Component({
selector: 'logs-window',
templateUrl: 'logs.template.html',
styles: [
`
pre {
margin: 0;
}
`,
],
providers: [
{
provide: INTERSECTION_ROOT,
useExisting: ElementRef,
},
],
})
export class LogsComponent {
readonly logs$ = inject(LogsService)
scroll = true
scrollTo(bottom: HTMLElement) {
if (this.scroll) bottom.scrollIntoView({ behavior: 'smooth' })
}
onBottom([{ isIntersecting }]: readonly IntersectionObserverEntry[]) {
this.scroll = isIntersecting
}
}

View File

@@ -0,0 +1,20 @@
import { CommonModule } from '@angular/common'
import { NgModule } from '@angular/core'
import { IntersectionObserverModule } from '@ng-web-apis/intersection-observer'
import { MutationObserverModule } from '@ng-web-apis/mutation-observer'
import { TuiScrollbarModule } from '@taiga-ui/core'
import { NgDompurifyModule } from '@tinkoff/ng-dompurify'
import { LogsComponent } from './logs.component'
@NgModule({
imports: [
CommonModule,
MutationObserverModule,
IntersectionObserverModule,
NgDompurifyModule,
TuiScrollbarModule,
],
declarations: [LogsComponent],
exports: [LogsComponent],
})
export class LogsModule {}

View File

@@ -0,0 +1,49 @@
import { inject, Injectable } from '@angular/core'
import { Log, toLocalIsoString } from '@start9labs/shared'
import {
bufferTime,
defer,
filter,
map,
Observable,
scan,
switchMap,
} from 'rxjs'
import { ApiService } from 'src/app/services/api/embassy-api.service'
var Convert = require('ansi-to-html')
var convert = new Convert({
newline: true,
bg: 'transparent',
colors: {
4: 'Cyan',
},
escapeXML: true,
})
function convertAnsi(entries: readonly any[]): string {
return entries
.map(
({ timestamp, message }) =>
`<b style="color: #FFF">${toLocalIsoString(
new Date(timestamp),
)}</b>&nbsp;&nbsp;${convert.toHtml(message)}`,
)
.join('<br />')
}
@Injectable({ providedIn: 'root' })
export class LogsService extends Observable<readonly string[]> {
private readonly api = inject(ApiService)
private readonly log$ = defer(() => this.api.initFollowLogs({})).pipe(
switchMap(({ guid }) => this.api.openWebsocket$<Log>(guid, {})),
bufferTime(250),
filter(logs => !!logs.length),
map(convertAnsi),
scan((logs: readonly string[], log) => [...logs, log], []),
)
constructor() {
super(subscriber => this.log$.subscribe(subscriber))
}
}

View File

@@ -0,0 +1,9 @@
<tui-scrollbar childList subtree (waMutationObserver)="scrollTo(bottom)">
<pre *ngFor="let log of logs$ | async" [innerHTML]="log | dompurify"></pre>
<section
#bottom
waIntersectionObserver
[style.padding.rem]="1"
(waIntersectionObservee)="onBottom($event)"
></section>
</tui-scrollbar>