mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 02:11:53 +00:00
fix dep error display, show starting if any health check starting, show disabled health check message, remove loader from service list, animated dots, better color (#3025)
* refector addresses to not need gateways array * fix dep error display, show starting if any health check starting, show disabled health check message, remove loader from service list, animated dots, better color * fix: fix action results textfields --------- Co-authored-by: waterplea <alexander@inkin.ru>
This commit is contained in:
@@ -110,6 +110,7 @@ body {
|
||||
animation-fill-mode: forwards;
|
||||
text-align: left;
|
||||
width: 1em;
|
||||
margin-left: -.3rem;
|
||||
}
|
||||
|
||||
@keyframes ellipsis-dot {
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
var(--tui-status-warning) 24%,
|
||||
transparent
|
||||
);
|
||||
--tui-status-info: rgba(128, 89, 229, 1);
|
||||
--tui-status-info: rgba(53, 96, 240, 1);
|
||||
--tui-status-info-pale: color-mix(
|
||||
in hsl,
|
||||
var(--tui-status-info) 12%,
|
||||
|
||||
@@ -166,12 +166,10 @@ export class InterfaceService {
|
||||
}, [] as AddressWithInfo[])
|
||||
|
||||
return {
|
||||
common: bestAddrs.map(a =>
|
||||
this.toDisplayAddress(a, gateways, host.publicDomains),
|
||||
),
|
||||
common: bestAddrs.map(a => this.toDisplayAddress(a, host.publicDomains)),
|
||||
uncommon: allAddressesWithInfo
|
||||
.filter(a => !bestAddrs.includes(a))
|
||||
.map(a => this.toDisplayAddress(a, gateways, host.publicDomains)),
|
||||
.map(a => this.toDisplayAddress(a, host.publicDomains)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,7 +312,6 @@ export class InterfaceService {
|
||||
|
||||
private toDisplayAddress(
|
||||
{ info, url, gateway }: AddressWithInfo,
|
||||
gateways: GatewayPlus[],
|
||||
publicDomains: Record<string, T.PublicDomainConfig>,
|
||||
): DisplayAddress {
|
||||
let access: DisplayAddress['access']
|
||||
@@ -360,11 +357,11 @@ export class InterfaceService {
|
||||
// ** Not Tor **
|
||||
} else {
|
||||
const port = info.hostname.sslPort || info.hostname.port
|
||||
const gateway = gateways.find(g => g.id === info.gateway.id)!
|
||||
gatewayName = gateway.name
|
||||
const g = gateway!
|
||||
gatewayName = g.name
|
||||
|
||||
const gatewayLanIpv4 = gateway.lanIpv4[0]
|
||||
const isWireguard = gateway.ipInfo.deviceType === 'wireguard'
|
||||
const gatewayLanIpv4 = g.lanIpv4[0]
|
||||
const isWireguard = g.ipInfo.deviceType === 'wireguard'
|
||||
|
||||
const localIdeal = this.i18n.transform('Ideal for local access')
|
||||
const lanRequired = this.i18n.transform(
|
||||
@@ -405,9 +402,9 @@ export class InterfaceService {
|
||||
),
|
||||
rootCaRequired,
|
||||
]
|
||||
if (!gateway.public) {
|
||||
if (!g.public) {
|
||||
bullets.push(
|
||||
`${portForwarding} "${gatewayName}": ${port} -> ${gateway.subnets.find(s => s.isIpv4())?.address}:${port}`,
|
||||
`${portForwarding} "${gatewayName}": ${port} -> ${g.subnets.find(s => s.isIpv4())?.address}:${port}`,
|
||||
)
|
||||
}
|
||||
} else {
|
||||
@@ -439,12 +436,12 @@ export class InterfaceService {
|
||||
if (info.public) {
|
||||
access = 'public'
|
||||
bullets = [
|
||||
`${dnsFor} ${info.hostname.value} ${resolvesTo} ${gateway.ipInfo.wanIp}`,
|
||||
`${dnsFor} ${info.hostname.value} ${resolvesTo} ${g.ipInfo.wanIp}`,
|
||||
]
|
||||
|
||||
if (!gateway.public) {
|
||||
if (!g.public) {
|
||||
bullets.push(
|
||||
`${portForwarding} "${gatewayName}": ${port} -> ${gateway.subnets.find(s => s.isIpv4())?.address}:${port === 443 ? 5443 : port}`,
|
||||
`${portForwarding} "${gatewayName}": ${port} -> ${g.subnets.find(s => s.isIpv4())?.address}:${port === 443 ? 5443 : port}`,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -97,10 +97,8 @@ export class ServiceHealthCheckComponent {
|
||||
return `${this.i18n.transform('Success')}: ${this.healthCheck.message || 'health check passing'}`
|
||||
case 'loading':
|
||||
case 'failure':
|
||||
return this.healthCheck.message
|
||||
// disabled
|
||||
default:
|
||||
return this.healthCheck.result
|
||||
case 'disabled':
|
||||
return this.healthCheck.message || this.healthCheck.result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,22 +6,26 @@ import {
|
||||
} from '@angular/core'
|
||||
import { i18nKey, i18nPipe } from '@start9labs/shared'
|
||||
import { tuiPure } from '@taiga-ui/cdk'
|
||||
import { TuiIcon, TuiLoader } from '@taiga-ui/core'
|
||||
import { TuiIcon } from '@taiga-ui/core'
|
||||
import { getProgressText } from 'src/app/routes/portal/routes/services/pipes/install-progress.pipe'
|
||||
import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
|
||||
import { renderPkgStatus } from 'src/app/services/pkg-status-rendering.service'
|
||||
import {
|
||||
PrimaryRendering,
|
||||
renderPkgStatus,
|
||||
} from 'src/app/services/pkg-status-rendering.service'
|
||||
|
||||
@Component({
|
||||
selector: 'td[appStatus]',
|
||||
template: `
|
||||
@if (loading) {
|
||||
<tui-loader size="s" />
|
||||
} @else {
|
||||
@if (!healthy) {
|
||||
<tui-icon icon="@tui.triangle-alert" class="g-warning" />
|
||||
}
|
||||
|
||||
<b [style.color]="color">{{ status | i18n }}</b>
|
||||
|
||||
@if (showDots) {
|
||||
<span class="loading-dots g-info"></span>
|
||||
}
|
||||
<b [style.color]="color">{{ status | i18n }}{{ dots }}</b>
|
||||
`,
|
||||
styles: `
|
||||
:host {
|
||||
@@ -37,7 +41,7 @@ import { renderPkgStatus } from 'src/app/services/pkg-status-rendering.service'
|
||||
}
|
||||
`,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [TuiIcon, TuiLoader, i18nPipe],
|
||||
imports: [TuiIcon, i18nPipe],
|
||||
})
|
||||
export class StatusComponent {
|
||||
@Input()
|
||||
@@ -58,10 +62,6 @@ export class StatusComponent {
|
||||
)
|
||||
}
|
||||
|
||||
get loading(): boolean {
|
||||
return this.color === 'var(--tui-status-info)'
|
||||
}
|
||||
|
||||
@tuiPure
|
||||
getStatus(pkg: PackageDataEntry) {
|
||||
return renderPkgStatus(pkg)
|
||||
@@ -72,35 +72,10 @@ export class StatusComponent {
|
||||
return `${this.i18n.transform('Installing')}... ${this.i18n.transform(getProgressText(this.pkg.stateInfo.installingInfo.progress.overall))}` as i18nKey
|
||||
}
|
||||
|
||||
switch (this.getStatus(this.pkg).primary) {
|
||||
case 'running':
|
||||
return 'Running'
|
||||
case 'stopped':
|
||||
return 'Stopped'
|
||||
case 'taskRequired':
|
||||
return 'Task Required'
|
||||
case 'updating':
|
||||
return 'Updating'
|
||||
case 'stopping':
|
||||
return 'Stopping'
|
||||
case 'starting':
|
||||
return 'Starting'
|
||||
case 'backingUp':
|
||||
return 'Backing Up'
|
||||
case 'restarting':
|
||||
return 'Restarting'
|
||||
case 'removing':
|
||||
return 'Removing'
|
||||
case 'restoring':
|
||||
return 'Restoring'
|
||||
case 'error':
|
||||
return 'Error'
|
||||
default:
|
||||
return 'Unknown'
|
||||
}
|
||||
return PrimaryRendering[this.getStatus(this.pkg).primary].display
|
||||
}
|
||||
|
||||
get dots(): '...' | '' {
|
||||
get showDots() {
|
||||
switch (this.getStatus(this.pkg).primary) {
|
||||
case 'updating':
|
||||
case 'stopping':
|
||||
@@ -108,9 +83,9 @@ export class StatusComponent {
|
||||
case 'backingUp':
|
||||
case 'restarting':
|
||||
case 'removing':
|
||||
return '...'
|
||||
return true
|
||||
default:
|
||||
return ''
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ import { QrCodeComponent } from 'ng-qrcode'
|
||||
tuiTextfield
|
||||
[readOnly]="true"
|
||||
[ngModel]="member.value"
|
||||
[style.border-inline-end-width.rem]="border"
|
||||
[type]="member.masked && masked ? 'password' : 'text'"
|
||||
/>
|
||||
@if (member.masked) {
|
||||
@@ -129,16 +128,6 @@ export class ActionSuccessMemberComponent {
|
||||
|
||||
masked = true
|
||||
|
||||
get border(): number {
|
||||
let border = 0
|
||||
|
||||
if (this.member.masked) border += 2
|
||||
if (this.member.copyable) border += 2
|
||||
if (this.member.qr) border += 2
|
||||
|
||||
return border
|
||||
}
|
||||
|
||||
show(template: TemplateRef<any>) {
|
||||
const masked = this.masked
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ import { SingleResult } from './types'
|
||||
tuiTextfield
|
||||
[readOnly]="true"
|
||||
[ngModel]="single.value"
|
||||
[style.border-inline-end-width.rem]="border"
|
||||
[type]="single.masked && masked ? 'password' : 'text'"
|
||||
/>
|
||||
@if (single.masked) {
|
||||
@@ -105,15 +104,6 @@ export class ActionSuccessSingleComponent {
|
||||
|
||||
masked = true
|
||||
|
||||
get border(): number {
|
||||
let border = 0
|
||||
|
||||
if (this.single.masked) border += 2
|
||||
if (this.single.copyable) border += 2
|
||||
|
||||
return border
|
||||
}
|
||||
|
||||
copy() {
|
||||
const el = this.input.nativeElement
|
||||
|
||||
|
||||
@@ -126,15 +126,16 @@ export class DepErrorService {
|
||||
const expected = currentDep?.versionRange || ''
|
||||
|
||||
// incorrect version
|
||||
if (!this.exver.satisfies(depManifest.version, expected)) {
|
||||
if (depManifest.satisfies.some(v => !this.exver.satisfies(v, expected))) {
|
||||
if (
|
||||
!this.exver.satisfies(depManifest.version, expected) &&
|
||||
!depManifest.satisfies.some(v => this.exver.satisfies(v, expected))
|
||||
) {
|
||||
return {
|
||||
expected,
|
||||
type: 'incorrectVersion',
|
||||
received: depManifest.version,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// action required
|
||||
if (
|
||||
|
||||
@@ -25,11 +25,21 @@ export function getInstalledPrimaryStatus({
|
||||
tasks,
|
||||
status,
|
||||
}: T.PackageDataEntry): PrimaryStatus {
|
||||
return Object.values(tasks).some(
|
||||
t => t.active && t.task.severity === 'critical',
|
||||
)
|
||||
? 'taskRequired'
|
||||
: status.main
|
||||
if (
|
||||
Object.values(tasks).some(t => t.active && t.task.severity === 'critical')
|
||||
) {
|
||||
return 'taskRequired'
|
||||
}
|
||||
|
||||
if (
|
||||
Object.values(status.main === 'running' && status.health)
|
||||
.filter(h => !!h)
|
||||
.some(h => h.result === 'starting')
|
||||
) {
|
||||
return 'starting'
|
||||
}
|
||||
|
||||
return status.main
|
||||
}
|
||||
|
||||
function getHealthStatus(status: T.MainStatus): T.HealthStatus | null {
|
||||
@@ -43,14 +53,14 @@ function getHealthStatus(status: T.MainStatus): T.HealthStatus | null {
|
||||
return 'failure'
|
||||
}
|
||||
|
||||
if (values.some(h => h.result === 'loading')) {
|
||||
return 'loading'
|
||||
}
|
||||
|
||||
if (values.some(h => h.result === 'starting')) {
|
||||
return 'starting'
|
||||
}
|
||||
|
||||
if (values.some(h => h.result === 'loading')) {
|
||||
return 'loading'
|
||||
}
|
||||
|
||||
return 'success'
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user