Merge branch 'feature/proxies' of github.com:Start9Labs/start-os into feature/proxies

This commit is contained in:
Aiden McClelland
2025-08-25 19:29:52 -06:00
13 changed files with 62 additions and 56 deletions

View File

@@ -575,4 +575,5 @@ export default {
608: 'Zweck', 608: 'Zweck',
609: 'Subdomains von', 609: 'Subdomains von',
610: 'Dynamisches DNS', 610: 'Dynamisches DNS',
611: 'Keine Service-Schnittstellen',
} satisfies i18n } satisfies i18n

View File

@@ -574,4 +574,5 @@ export const ENGLISH = {
'Purpose': 608, // as in, the reason for a thing to exist 'Purpose': 608, // as in, the reason for a thing to exist
'subdomains of': 609, // this is a partial sentence. A domain name will be added after "of" to complete the sentence. 'subdomains of': 609, // this is a partial sentence. A domain name will be added after "of" to complete the sentence.
'Dynamic DNS': 610, 'Dynamic DNS': 610,
'No service interfaces': 611, // as in, there are no available interfaces (API, UI, etc) for this software application
} as const } as const

View File

@@ -575,4 +575,5 @@ export default {
608: 'Propósito', 608: 'Propósito',
609: 'Subdominios de', 609: 'Subdominios de',
610: 'DNS dinámico', 610: 'DNS dinámico',
611: 'Sin interfaces de servicio',
} satisfies i18n } satisfies i18n

View File

@@ -575,4 +575,5 @@ export default {
608: 'But', 608: 'But',
609: 'Sous-domaines de', 609: 'Sous-domaines de',
610: 'DNS dynamique', 610: 'DNS dynamique',
611: 'Aucune interface de service',
} satisfies i18n } satisfies i18n

View File

@@ -575,4 +575,5 @@ export default {
608: 'Cel', 608: 'Cel',
609: 'Subdomeny', 609: 'Subdomeny',
610: 'Dynamiczny DNS', 610: 'Dynamiczny DNS',
611: 'Brak interfejsów usług',
} satisfies i18n } satisfies i18n

View File

@@ -95,7 +95,7 @@ export class ServiceDependenciesComponent {
return 'Incorrect version' return 'Incorrect version'
case 'notRunning': case 'notRunning':
return 'Not running' return 'Not running'
case 'actionRequired': case 'taskRequired':
return 'Task Required' return 'Task Required'
case 'healthChecksFailed': case 'healthChecksFailed':
return 'Required health check not passing' return 'Required health check not passing'

View File

@@ -9,6 +9,7 @@ import { tuiDefaultSort } from '@taiga-ui/cdk'
import { PackageDataEntry } from 'src/app/services/patch-db/data-model' import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
import { ServiceInterfaceItemComponent } from './interface-item.component' import { ServiceInterfaceItemComponent } from './interface-item.component'
import { i18nPipe } from '@start9labs/shared' import { i18nPipe } from '@start9labs/shared'
import { PlaceholderComponent } from '../../../components/placeholder.component'
@Component({ @Component({
selector: 'service-interfaces', selector: 'service-interfaces',
@@ -31,6 +32,10 @@ import { i18nPipe } from '@start9labs/shared'
[pkg]="pkg()" [pkg]="pkg()"
[disabled]="disabled()" [disabled]="disabled()"
></tr> ></tr>
} @empty {
<app-placeholder icon="@tui.monitor-x">
{{ 'No service interfaces' | i18n }}
</app-placeholder>
} }
</tbody> </tbody>
</table> </table>
@@ -42,7 +47,12 @@ import { i18nPipe } from '@start9labs/shared'
`, `,
host: { class: 'g-card' }, host: { class: 'g-card' },
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
imports: [ServiceInterfaceItemComponent, TuiTable, i18nPipe], imports: [
ServiceInterfaceItemComponent,
TuiTable,
i18nPipe,
PlaceholderComponent,
],
}) })
export class ServiceInterfacesComponent { export class ServiceInterfacesComponent {
readonly pkg = input.required<PackageDataEntry>() readonly pkg = input.required<PackageDataEntry>()

View File

@@ -52,7 +52,7 @@ export class StatusComponent {
const { primary, health } = this.getStatus(this.pkg) const { primary, health } = this.getStatus(this.pkg)
return ( return (
!this.hasDepErrors && !this.hasDepErrors &&
primary !== 'actionRequired' && primary !== 'taskRequired' &&
primary !== 'error' && primary !== 'error' &&
health !== 'failure' health !== 'failure'
) )
@@ -77,7 +77,7 @@ export class StatusComponent {
return 'Running' return 'Running'
case 'stopped': case 'stopped':
return 'Stopped' return 'Stopped'
case 'actionRequired': case 'taskRequired':
return 'Task Required' return 'Task Required'
case 'updating': case 'updating':
return 'Updating' return 'Updating'
@@ -118,7 +118,7 @@ export class StatusComponent {
switch (this.getStatus(this.pkg).primary) { switch (this.getStatus(this.pkg).primary) {
case 'running': case 'running':
return 'var(--tui-status-positive)' return 'var(--tui-status-positive)'
case 'actionRequired': case 'taskRequired':
return 'var(--tui-status-warning)' return 'var(--tui-status-warning)'
case 'error': case 'error':
return 'var(--tui-status-negative)' return 'var(--tui-status-negative)'

View File

@@ -450,15 +450,6 @@ export namespace RR {
export type GetRegistryPackagesRes = GetPackagesRes export type GetRegistryPackagesRes = GetPackagesRes
} }
export type Breakages = {
[id: string]: TaggedDependencyError
}
export type TaggedDependencyError = {
dependency: string
error: DependencyError
}
interface MetricData { interface MetricData {
value: string value: string
unit: string unit: string
@@ -622,41 +613,6 @@ export type Encrypted = {
encrypted: string encrypted: string
} }
export type DependencyError =
| DependencyErrorNotInstalled
| DependencyErrorNotRunning
| DependencyErrorIncorrectVersion
| DependencyErrorActionRequired
| DependencyErrorHealthChecksFailed
| DependencyErrorTransitive
export type DependencyErrorNotInstalled = {
type: 'notInstalled'
}
export type DependencyErrorNotRunning = {
type: 'notRunning'
}
export type DependencyErrorIncorrectVersion = {
type: 'incorrectVersion'
expected: string // version range
received: string // version
}
export interface DependencyErrorActionRequired {
type: 'actionRequired'
}
export type DependencyErrorHealthChecksFailed = {
type: 'healthChecksFailed'
check: T.NamedHealthCheckResult
}
export type DependencyErrorTransitive = {
type: 'transitive'
}
// @TODO 041 // @TODO 041
// export namespace RR041 { // export namespace RR041 {

View File

@@ -10,11 +10,46 @@ import {
import deepEqual from 'fast-deep-equal' import deepEqual from 'fast-deep-equal'
import { Observable } from 'rxjs' import { Observable } from 'rxjs'
import { isInstalled } from 'src/app/utils/get-package-data' import { isInstalled } from 'src/app/utils/get-package-data'
import { DependencyError } from './api/api.types' import { T } from '@start9labs/start-sdk'
export type AllDependencyErrors = Record<string, PkgDependencyErrors> export type AllDependencyErrors = Record<string, PkgDependencyErrors>
export type PkgDependencyErrors = Record<string, DependencyError | null> export type PkgDependencyErrors = Record<string, DependencyError | null>
export type DependencyError =
| DependencyErrorNotInstalled
| DependencyErrorNotRunning
| DependencyErrorIncorrectVersion
| DependencyErrorTaskRequired
| DependencyErrorHealthChecksFailed
| DependencyErrorTransitive
export type DependencyErrorNotInstalled = {
type: 'notInstalled'
}
export type DependencyErrorNotRunning = {
type: 'notRunning'
}
export type DependencyErrorIncorrectVersion = {
type: 'incorrectVersion'
expected: string // version range
received: string // version
}
export interface DependencyErrorTaskRequired {
type: 'taskRequired'
}
export type DependencyErrorHealthChecksFailed = {
type: 'healthChecksFailed'
check: T.NamedHealthCheckResult
}
export type DependencyErrorTransitive = {
type: 'transitive'
}
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',
}) })
@@ -113,7 +148,7 @@ export class DepErrorService {
) )
) { ) {
return { return {
type: 'actionRequired', type: 'taskRequired',
} }
} }

View File

@@ -84,7 +84,6 @@ export class FormService {
currentValue?: any, currentValue?: any,
): UntypedFormGroup | UntypedFormArray | UntypedFormControl { ): UntypedFormGroup | UntypedFormArray | UntypedFormControl {
let value: any let value: any
console.log(spec)
switch (spec.type) { switch (spec.type) {
case 'text': case 'text':
if (currentValue !== undefined) { if (currentValue !== undefined) {
@@ -140,6 +139,8 @@ export class FormService {
case 'multiselect': case 'multiselect':
value = currentValue === undefined ? spec.default : currentValue value = currentValue === undefined ? spec.default : currentValue
return this.formBuilder.control(value, multiselectValidators(spec)) return this.formBuilder.control(value, multiselectValidators(spec))
case 'hidden':
return this.formBuilder.control(currentValue || null)
case 'file': case 'file':
return this.formBuilder.control(null, fileValidators(spec)) return this.formBuilder.control(null, fileValidators(spec))
default: default:

View File

@@ -115,7 +115,6 @@ export class MarketplaceService {
flavor: string | null, flavor: string | null,
registryUrl?: string, registryUrl?: string,
): Observable<MarketplacePkg> { ): Observable<MarketplacePkg> {
console.log('HERE')
return this.currentRegistry$.pipe( return this.currentRegistry$.pipe(
switchMap(registry => { switchMap(registry => {
const url = registryUrl || registry.url const url = registryUrl || registry.url

View File

@@ -28,7 +28,7 @@ export function getInstalledPrimaryStatus({
return Object.values(tasks) return Object.values(tasks)
.filter(t => !!t) .filter(t => !!t)
.some(t => t.active && t.task.severity === 'critical') .some(t => t.active && t.task.severity === 'critical')
? 'actionRequired' ? 'taskRequired'
: status.main : status.main
} }
@@ -71,7 +71,7 @@ export type PrimaryStatus =
| 'restarting' | 'restarting'
| 'stopped' | 'stopped'
| 'backingUp' | 'backingUp'
| 'actionRequired' | 'taskRequired'
| 'error' | 'error'
export type DependencyStatus = 'warning' | 'satisfied' export type DependencyStatus = 'warning' | 'satisfied'
@@ -127,7 +127,7 @@ export const PrimaryRendering: Record<PrimaryStatus, StatusRendering> = {
color: 'success', color: 'success',
showDots: false, showDots: false,
}, },
actionRequired: { taskRequired: {
display: 'Task Required', display: 'Task Required',
color: 'warning', color: 'warning',
showDots: false, showDots: false,