mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 20:14:49 +00:00
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:
33
web/projects/ui/src/app/pages/init/logs/logs.component.ts
Normal file
33
web/projects/ui/src/app/pages/init/logs/logs.component.ts
Normal 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
|
||||
}
|
||||
}
|
||||
20
web/projects/ui/src/app/pages/init/logs/logs.module.ts
Normal file
20
web/projects/ui/src/app/pages/init/logs/logs.module.ts
Normal 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 {}
|
||||
49
web/projects/ui/src/app/pages/init/logs/logs.service.ts
Normal file
49
web/projects/ui/src/app/pages/init/logs/logs.service.ts
Normal 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> ${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))
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user