fix: address todos (#2578)

This commit is contained in:
Alex Inkin
2024-03-28 00:27:51 +08:00
committed by GitHub
parent 641e829e3f
commit 8cfd994170
16 changed files with 359 additions and 192 deletions

View File

@@ -2,7 +2,9 @@ import { AsyncPipe } from '@angular/common'
import {
ChangeDetectionStrategy,
Component,
computed,
inject,
input,
Input,
} from '@angular/core'
import { TuiLetModule, tuiPure } from '@taiga-ui/cdk'
@@ -22,11 +24,11 @@ import { Manifest } from '@start9labs/marketplace'
standalone: true,
selector: 'fieldset[appControls]',
template: `
@if (pkg.status.main.status === 'running') {
@if (pkg().status.main.status === 'running') {
<button
tuiIconButton
iconLeft="tuiIconSquare"
(click)="actions.stop(manifest)"
(click)="actions.stop(manifest())"
>
Stop
</button>
@@ -34,7 +36,7 @@ import { Manifest } from '@start9labs/marketplace'
<button
tuiIconButton
iconLeft="tuiIconRotateCw"
(click)="actions.restart(manifest)"
(click)="actions.restart(manifest())"
>
Restart
</button>
@@ -43,8 +45,8 @@ import { Manifest } from '@start9labs/marketplace'
*tuiLet="hasUnmet() | async as hasUnmet"
tuiIconButton
iconLeft="tuiIconPlay"
[disabled]="!pkg.status.configured"
(click)="actions.start(manifest, !!hasUnmet)"
[disabled]="!pkg().status.configured"
(click)="actions.start(manifest(), !!hasUnmet)"
>
Start
</button>
@@ -52,39 +54,33 @@ import { Manifest } from '@start9labs/marketplace'
<button
tuiIconButton
iconLeft="tuiIconTool"
(click)="actions.configure(manifest)"
(click)="actions.configure(manifest())"
>
Configure
</button>
}
<app-ui-launch [pkg]="pkg" />
<app-ui-launch [pkg]="pkg()" />
`,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [TuiButtonModule, UILaunchComponent, TuiLetModule, AsyncPipe],
providers: [tuiButtonOptionsProvider({ size: 's', appearance: 'none' })],
styles: ':host { padding: 0; border: none }',
})
export class ControlsComponent {
private readonly errors = inject(DepErrorService)
@Input()
pkg!: PackageDataEntry
get manifest(): Manifest {
return getManifest(this.pkg)
}
readonly actions = inject(ActionsService)
@tuiPure
hasUnmet(): Observable<boolean> {
const id = this.manifest.id
return this.errors.getPkgDepErrors$(id).pipe(
pkg = input.required<PackageDataEntry>()
readonly manifest = computed(() => getManifest(this.pkg()))
readonly hasUnmet = computed(() =>
this.errors.getPkgDepErrors$(this.manifest().id).pipe(
map(errors =>
Object.keys(this.pkg.currentDependencies)
.map(id => !!(errors[id] as any)?.[id]) // @TODO-Alex fix
Object.keys(this.pkg().currentDependencies)
.map(id => !!(errors[id] as any)?.[id]) // @TODO fix type
.some(Boolean),
),
)
}
),
)
}

View File

@@ -16,7 +16,7 @@ import { ToManifestPipe } from '../../pipes/to-manifest'
<th [style.width.rem]="3"></th>
<th>Name</th>
<th>Version</th>
<th [style.width.rem]="12">Status</th>
<th [style.width.rem]="13">Status</th>
<th [style.width.rem]="8" [style.text-align]="'center'">Controls</th>
</tr>
</thead>

View File

@@ -1,4 +1,9 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
import {
ChangeDetectionStrategy,
Component,
inject,
Input,
} from '@angular/core'
import { tuiPure } from '@taiga-ui/cdk'
import { TuiLoaderModule } from '@taiga-ui/core'
import { TuiIconModule } from '@taiga-ui/experimental'
@@ -35,8 +40,11 @@ import { InstallingProgressDisplayPipe } from '../service/pipes/install-progress
`,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [TuiIconModule, TuiLoaderModule],
providers: [InstallingProgressDisplayPipe],
})
export class StatusComponent {
private readonly pipe = inject(InstallingProgressDisplayPipe)
@Input()
pkg!: PackageDataEntry
@@ -64,7 +72,7 @@ export class StatusComponent {
get status(): string {
if (this.pkg.stateInfo.installingInfo) {
return `Installing...${new InstallingProgressDisplayPipe().transform(this.pkg.stateInfo.installingInfo.progress.overall)}`
return `Installing... ${this.pipe.transform(this.pkg.stateInfo.installingInfo.progress.overall)}`
}
switch (this.getStatus(this.pkg).primary) {

View File

@@ -43,17 +43,15 @@ import {
</ng-template>
</tui-hosted-dropdown>
} @else {
@if (interfaces[0]; as info) {
<a
tuiIconButton
iconLeft="tuiIconExternalLink"
target="_blank"
rel="noreferrer"
[attr.href]="getHref(info)"
>
{{ info.name }}
</a>
}
<a
tuiIconButton
iconLeft="tuiIconExternalLink"
target="_blank"
rel="noreferrer"
[attr.href]="getHref(interfaces[0])"
>
{{ interfaces[0]?.name }}
</a>
}
`,
changeDetection: ChangeDetectionStrategy.OnPush,

View File

@@ -1,8 +1,15 @@
import { inject, Injectable } from '@angular/core'
import {
ChangeDetectionStrategy,
Component,
inject,
Injectable,
} from '@angular/core'
import { FormsModule } from '@angular/forms'
import { TuiAlertService, TuiDialogService } from '@taiga-ui/core'
import * as argon2 from '@start9labs/argon2'
import { ErrorService, LoadingService } from '@start9labs/shared'
import { TUI_PROMPT } from '@taiga-ui/kit'
import { TUI_PROMPT, TuiCheckboxLabeledModule } from '@taiga-ui/kit'
import { PolymorpheusComponent } from '@tinkoff/ng-polymorpheus'
import { PatchDB } from 'patch-db-client'
import { filter, firstValueFrom, from, take } from 'rxjs'
import { switchMap } from 'rxjs/operators'
@@ -30,6 +37,8 @@ export class SettingsService {
private readonly api = inject(ApiService)
private readonly isTor = inject(ConfigService).isTor()
wipe = false
readonly settings: Record<string, readonly SettingBtn[]> = {
General: [
{
@@ -122,19 +131,19 @@ export class SettingsService {
await this.proxyService.presentModalSetOutboundProxy(proxy)
}
// @TODO-Alex previous this was done in experimental settings using a template ref.
private promptResetTor() {
this.wipe = false
this.dialogs
.open(TUI_PROMPT, {
label: this.isTor ? 'Warning' : 'Confirm',
data: {
content: '@TODO how to display a checkbox in here?',
content: new PolymorpheusComponent(WipeComponent),
yes: 'Reset',
no: 'Cancel',
},
})
.pipe(filter(Boolean))
.subscribe(() => this.resetTor(true))
.subscribe(() => this.resetTor(this.wipe))
}
private async resetTor(wipeState: boolean) {
@@ -258,3 +267,30 @@ export class SettingsService {
}
}
}
@Component({
standalone: true,
template: `
<p>
@if (isTor) {
You are currently connected over Tor. If you reset the Tor daemon, you
will lose connectivity until it comes back online.
} @else {
Reset Tor?
}
</p>
<p>
Optionally wipe state to forcibly acquire new guard nodes. It is
recommended to try without wiping state first.
</p>
<tui-checkbox-labeled size="l" [(ngModel)]="service.wipe">
Wipe state
</tui-checkbox-labeled>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [TuiCheckboxLabeledModule, FormsModule],
})
class WipeComponent {
readonly isTor = inject(ConfigService).isTor()
readonly service = inject(SettingsService)
}

View File

@@ -1,4 +1,3 @@
import { NgIf } from '@angular/common'
import { Component, inject, Input } from '@angular/core'
import { RouterLink } from '@angular/router'
import {
@@ -27,17 +26,17 @@ import {
TuiProgressModule,
} from '@taiga-ui/kit'
import { NgDompurifyModule } from '@tinkoff/ng-dompurify'
import { PatchDB } from 'patch-db-client'
import { InstallingProgressPipe } from 'src/app/apps/portal/routes/service/pipes/install-progress.pipe'
import { MarketplaceService } from 'src/app/services/marketplace.service'
import {
DataModel,
InstalledState,
PackageDataEntry,
UpdatingState,
} from 'src/app/services/patch-db/data-model'
import { MarketplaceService } from 'src/app/services/marketplace.service'
import { hasCurrentDeps } from 'src/app/util/has-deps'
import { InstallingProgressPipe } from '../../../service/pipes/install-progress.pipe'
import { PatchDB } from 'patch-db-client'
import { getAllPackages } from 'src/app/util/get-package-data'
import { hasCurrentDeps } from 'src/app/util/has-deps'
@Component({
selector: 'updates-item',
@@ -56,29 +55,30 @@ import { getAllPackages } from 'src/app/util/get-package-data'
</div>
<div [style.color]="'var(--tui-negative)'">{{ errors }}</div>
</div>
<tui-progress-circle
*ngIf="localPkg.stateInfo.state === 'updating'; else button"
style="color: var(--tui-positive)"
[max]="100"
[value]="
(localPkg.stateInfo.installingInfo.progress.overall
| installingProgress) || 0
"
/>
<ng-template #button>
<button
*ngIf="ready; else queued"
tuiButton
@if (localPkg.stateInfo.state === 'updating') {
<tui-progress-circle
class="g-success"
size="s"
[appearance]="errors ? 'secondary-destructive' : 'primary'"
(click.stop)="onClick()"
>
{{ errors ? 'Retry' : 'Update' }}
</button>
</ng-template>
<ng-template #queued>
<tui-loader [style.width.rem]="2" [inheritColor]="true" />
</ng-template>
[max]="1"
[value]="
(localPkg.stateInfo.installingInfo.progress.overall
| installingProgress) || 0
"
/>
} @else {
@if (ready) {
<button
tuiButton
size="s"
[appearance]="errors ? 'destructive' : 'primary'"
(click.stop)="onClick()"
>
{{ errors ? 'Retry' : 'Update' }}
</button>
} @else {
<tui-loader [style.width.rem]="2" [inheritColor]="true" />
}
}
</div>
<ng-template tuiAccordionItemContent>
<strong>What's new</strong>
@@ -114,7 +114,6 @@ import { getAllPackages } from 'src/app/util/get-package-data'
],
standalone: true,
imports: [
NgIf,
RouterLink,
EmverPipesModule,
MarkdownPipeModule,

View File

@@ -15,8 +15,8 @@ import {
UpdatingState,
} from 'src/app/services/patch-db/data-model'
import { ConfigService } from 'src/app/services/config.service'
import { FilterUpdatesPipe } from './pipes/filter-updates.pipe'
import { UpdatesItemComponent } from './components/item.component'
import { FilterUpdatesPipe } from 'src/app/apps/portal/routes/system/updates/filter-updates.pipe'
import { UpdatesItemComponent } from 'src/app/apps/portal/routes/system/updates/item.component'
import { isInstalled, isUpdating } from 'src/app/util/get-package-data'
@Component({

View File

@@ -42,9 +42,12 @@ export class BadgeService {
pairwise(),
filter(([prev, curr]) =>
Object.values(prev).some(p => {
const id = getManifest(p).id
!curr[id] ||
const { id } = getManifest(p)
return (
!curr[id] ||
(p.stateInfo.installingInfo && !curr[id].stateInfo.installingInfo)
)
}),
),
map(([_, curr]) => curr),
@@ -73,7 +76,6 @@ export class BadgeService {
new Set<string>(),
).size,
),
// @TODO-Alex shareReplay is preventing the badge from decrementing
shareReplay(1),
)

View File

@@ -9,8 +9,7 @@ import { LocalStorageBootstrap } from './patch-db/local-storage-bootstrap'
@Injectable({
providedIn: 'root',
})
export class PatchMonitorService extends Observable<any> {
// @TODO-Alex not happy with Observable<void>
export class PatchMonitorService extends Observable<unknown> {
private readonly stream$ = this.authService.isVerified$.pipe(
tap(verified =>
verified ? this.patch.start(this.bootstrapper) : this.patch.stop(),

View File

@@ -24,9 +24,9 @@ export async function getAllPackages(
}
export function getManifest(pkg: PackageDataEntry): Manifest {
if (isInstalled(pkg) || isRemoving(pkg)) return pkg.stateInfo.manifest
return (pkg.stateInfo as InstallingState).installingInfo.newManifest
return isInstalling(pkg)
? pkg.stateInfo.installingInfo.newManifest
: pkg.stateInfo.manifest!
}
export function isInstalled(