+
@if (installingInfo) {
-
+
Installing
{{ installingInfo.progress.overall | installingProgressString }}
-
+
} @else {
-
- {{ connected ? rendering.display : 'Unknown' }}
- @if (rendering.showDots) {
-
- }
+
+ {{ text }}
+ @if (text === 'Action Required') {
+ See below
+ }
+
+ @if (rendering.showDots) {
+
+ }
+
}
@@ -39,17 +37,29 @@ import { InstallingProgressDisplayPipe } from '../pipes/install-progress.pipe'
styles: [
`
:host {
- display: grid;
- grid-template-rows: min-content 1fr;
- align-items: center;
- font: var(--tui-font-heading-6);
- text-align: center;
+ grid-column: span 2;
}
- status {
- display: grid;
- grid-template-rows: min-content 1fr 1fr;
+ h3 {
+ font: var(--tui-font-heading-4);
+ font-weight: normal;
+ margin: 0;
+ }
+
+ div {
+ display: flex;
+ flex-direction: column;
align-items: center;
+ justify-content: center;
+ flex: 1;
+ padding: 1rem 0;
+ }
+
+ small {
+ display: block;
+ font: var(--tui-font-text-l);
+ color: var(--tui-text-secondary);
+ text-align: center;
}
tui-loader {
@@ -57,12 +67,24 @@ import { InstallingProgressDisplayPipe } from '../pipes/install-progress.pipe'
vertical-align: bottom;
margin: 0 0.25rem -0.125rem 0;
}
+
+ :host-context(tui-root._mobile) {
+ div {
+ flex-direction: row;
+ justify-content: space-between;
+ padding: 0.5rem 0;
+ }
+
+ small {
+ text-align: left;
+ }
+ }
`,
],
host: { class: 'g-card' },
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
- imports: [InstallingProgressDisplayPipe, TuiIcon, TuiLoader],
+ imports: [InstallingProgressDisplayPipe, TuiLoader],
})
export class ServiceStatusComponent {
@Input({ required: true })
@@ -74,6 +96,10 @@ export class ServiceStatusComponent {
@Input()
connected = false
+ get text() {
+ return this.connected ? this.rendering.display : 'Unknown'
+ }
+
get class(): string | null {
if (!this.connected) return null
@@ -94,21 +120,4 @@ export class ServiceStatusComponent {
get rendering() {
return PrimaryRendering[this.status]
}
-
- get icon(): string {
- if (!this.connected) return '@tui.circle'
-
- switch (this.rendering.color) {
- case 'danger':
- return '@tui.circle-x'
- case 'warning':
- return '@tui.circle-alert'
- case 'success':
- return '@tui.circle-check'
- case 'primary':
- return '@tui.circle-minus'
- default:
- return '@tui.circle'
- }
- }
}
diff --git a/web/projects/ui/src/app/routes/portal/routes/services/dashboard/dashboard.component.ts b/web/projects/ui/src/app/routes/portal/routes/services/dashboard/dashboard.component.ts
index dc55d5a77..c8c9b23a4 100644
--- a/web/projects/ui/src/app/routes/portal/routes/services/dashboard/dashboard.component.ts
+++ b/web/projects/ui/src/app/routes/portal/routes/services/dashboard/dashboard.component.ts
@@ -5,6 +5,7 @@ import { ToManifestPipe } from 'src/app/routes/portal/pipes/to-manifest'
import { DepErrorService } from 'src/app/services/dep-error.service'
import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
import { getInstalledPrimaryStatus } from 'src/app/services/pkg-status-rendering.service'
+import { TitleDirective } from 'src/app/services/title.service'
import { getManifest } from 'src/app/utils/get-package-data'
import { ServiceComponent } from './service.component'
import { ServicesService } from './services.service'
@@ -12,6 +13,7 @@ import { ServicesService } from './services.service'
@Component({
standalone: true,
template: `
+
Services
@@ -55,7 +57,7 @@ import { ServicesService } from './services.service'
}
`,
host: { class: 'g-page' },
- imports: [ServiceComponent, ToManifestPipe, TuiTable],
+ imports: [ServiceComponent, ToManifestPipe, TuiTable, TitleDirective],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export default class DashboardComponent {
diff --git a/web/projects/ui/src/app/routes/portal/routes/services/routes/about.component.ts b/web/projects/ui/src/app/routes/portal/routes/services/routes/about.component.ts
index 62ae91a09..79dbdeaa3 100644
--- a/web/projects/ui/src/app/routes/portal/routes/services/routes/about.component.ts
+++ b/web/projects/ui/src/app/routes/portal/routes/services/routes/about.component.ts
@@ -41,7 +41,7 @@ import ServiceMarkdownRoute from './markdown.component'
display: flex;
flex-direction: column;
max-width: 32rem;
- padding: 0.75rem;
+ padding: 0.5rem 1rem;
}
`,
changeDetection: ChangeDetectionStrategy.OnPush,
diff --git a/web/projects/ui/src/app/routes/portal/routes/services/routes/actions.component.ts b/web/projects/ui/src/app/routes/portal/routes/services/routes/actions.component.ts
index 68500ab1a..a8276bd2c 100644
--- a/web/projects/ui/src/app/routes/portal/routes/services/routes/actions.component.ts
+++ b/web/projects/ui/src/app/routes/portal/routes/services/routes/actions.component.ts
@@ -55,14 +55,6 @@ const OTHER = 'Other Custom Actions'
flex-direction: column;
margin-bottom: 2rem;
}
-
- [tuiCell] {
- margin: 0 -1rem;
-
- &:last-child {
- margin-bottom: -0.75rem;
- }
- }
`,
host: { class: 'g-subpage' },
changeDetection: ChangeDetectionStrategy.OnPush,
diff --git a/web/projects/ui/src/app/routes/portal/routes/services/routes/interface.component.ts b/web/projects/ui/src/app/routes/portal/routes/services/routes/interface.component.ts
index 10639a78f..1db5a587b 100644
--- a/web/projects/ui/src/app/routes/portal/routes/services/routes/interface.component.ts
+++ b/web/projects/ui/src/app/routes/portal/routes/services/routes/interface.component.ts
@@ -1,53 +1,65 @@
-import { CommonModule } from '@angular/common'
-import { ChangeDetectionStrategy, Component, inject } from '@angular/core'
-import { ActivatedRoute } from '@angular/router'
+import {
+ ChangeDetectionStrategy,
+ Component,
+ computed,
+ inject,
+ input,
+} from '@angular/core'
+import { toSignal } from '@angular/core/rxjs-interop'
+import { RouterLink } from '@angular/router'
import { getPkgId } from '@start9labs/shared'
+import { TuiButton } from '@taiga-ui/core'
import { PatchDB } from 'patch-db-client'
-import { combineLatest, map } from 'rxjs'
import { InterfaceComponent } from 'src/app/routes/portal/components/interfaces/interface.component'
-import { DataModel } from 'src/app/services/patch-db/data-model'
-import { getAddresses } from '../../../components/interfaces/interface.utils'
import { ConfigService } from 'src/app/services/config.service'
+import { DataModel } from 'src/app/services/patch-db/data-model'
+import { TitleDirective } from 'src/app/services/title.service'
+import { getAddresses } from '../../../components/interfaces/interface.utils'
@Component({
template: `
-
+
+ Back
+ {{ interface()?.name }}
+
+ @if (interface(); as serviceInterface) {
+
+ }
`,
host: { class: 'g-subpage' },
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
- imports: [CommonModule, InterfaceComponent],
+ imports: [InterfaceComponent, RouterLink, TuiButton, TitleDirective],
})
export default class ServiceInterfaceRoute {
- private readonly patch = inject>(PatchDB)
private readonly config = inject(ConfigService)
- readonly context = {
- packageId: getPkgId(),
- interfaceId:
- inject(ActivatedRoute).snapshot.paramMap.get('interfaceId') || '',
- }
+ readonly pkgId = getPkgId()
+ readonly interfaceId = input('')
- readonly interfacesWithAddresses$ = combineLatest([
- this.patch.watch$(
- 'packageData',
- this.context.packageId,
- 'serviceInterfaces',
- this.context.interfaceId,
- ),
- this.patch.watch$('packageData', this.context.packageId, 'hosts'),
- ]).pipe(
- map(([iFace, hosts]) => ({
- ...iFace,
- addresses: getAddresses(
- iFace,
- hosts[iFace.addressInfo.hostId],
- this.config,
- ),
- })),
+ readonly pkg = toSignal(
+ inject>(PatchDB).watch$('packageData', this.pkgId),
)
+
+ readonly interface = computed(() => {
+ const pkg = this.pkg()
+ const id = this.interfaceId()
+
+ if (!pkg || !id) {
+ return
+ }
+
+ const { serviceInterfaces, hosts } = pkg
+ const item = serviceInterfaces[this.interfaceId()]
+ const host = hosts[item.addressInfo.hostId]
+
+ return {
+ ...item,
+ public: host.bindings[item.addressInfo.internalPort].net.public,
+ addresses: getAddresses(item, host, this.config),
+ }
+ })
}
diff --git a/web/projects/ui/src/app/routes/portal/routes/services/routes/outlet.component.ts b/web/projects/ui/src/app/routes/portal/routes/services/routes/outlet.component.ts
index f67ae399f..abfb90b5f 100644
--- a/web/projects/ui/src/app/routes/portal/routes/services/routes/outlet.component.ts
+++ b/web/projects/ui/src/app/routes/portal/routes/services/routes/outlet.component.ts
@@ -6,12 +6,13 @@ import {
} from '@angular/core'
import { toSignal } from '@angular/core/rxjs-interop'
import { ActivatedRoute, Router, RouterModule } from '@angular/router'
-import { TuiAppearance, TuiIcon, TuiTitle } from '@taiga-ui/core'
+import { TuiAppearance, TuiButton, TuiIcon, TuiTitle } from '@taiga-ui/core'
import { TuiAvatar, TuiFade } from '@taiga-ui/kit'
import { TuiCell, tuiCellOptionsProvider } from '@taiga-ui/layout'
import { PatchDB } from 'patch-db-client'
import { distinctUntilChanged, filter, map, switchMap, tap } from 'rxjs'
import { DataModel } from 'src/app/services/patch-db/data-model'
+import { TitleDirective } from 'src/app/services/title.service'
import { getManifest } from 'src/app/utils/get-package-data'
const ICONS = {
@@ -25,6 +26,13 @@ const ICONS = {
@Component({
template: `
@if (service()) {
+
+
Back
+
+
+
+
{{ manifest()?.title }}
+