diff --git a/web/projects/shared/src/i18n/dictionaries/de.ts b/web/projects/shared/src/i18n/dictionaries/de.ts
index 8d148b0d1..5495c2c6e 100644
--- a/web/projects/shared/src/i18n/dictionaries/de.ts
+++ b/web/projects/shared/src/i18n/dictionaries/de.ts
@@ -99,6 +99,7 @@ export default {
101: 'Sie haben nicht gespeicherte Änderungen. Möchten Sie die Seite wirklich verlassen?',
102: 'Verlassen',
103: 'Sind Sie sicher?',
+ 104: 'Neues Netzwerk-Gateway',
108: 'Öffentlich',
109: 'privat',
111: 'Keine Onion-Domains',
diff --git a/web/projects/shared/src/i18n/dictionaries/en.ts b/web/projects/shared/src/i18n/dictionaries/en.ts
index 08e9382be..737fe5af5 100644
--- a/web/projects/shared/src/i18n/dictionaries/en.ts
+++ b/web/projects/shared/src/i18n/dictionaries/en.ts
@@ -98,6 +98,7 @@ export const ENGLISH = {
'You have unsaved changes. Are you sure you want to leave?': 101,
'Leave': 102,
'Are you sure?': 103,
+ 'New gateway': 104, // as in, a network gateway
'public': 108,
'private': 109,
'No Tor domains': 111,
diff --git a/web/projects/shared/src/i18n/dictionaries/es.ts b/web/projects/shared/src/i18n/dictionaries/es.ts
index 825100b30..2f6ef60a3 100644
--- a/web/projects/shared/src/i18n/dictionaries/es.ts
+++ b/web/projects/shared/src/i18n/dictionaries/es.ts
@@ -99,6 +99,7 @@ export default {
101: 'Tienes cambios no guardados. ¿Estás seguro de que deseas salir?',
102: 'Salir',
103: '¿Estás seguro?',
+ 104: 'Nueva puerta de enlace de red',
108: 'público',
109: 'privado',
111: 'Sin dominios onion',
diff --git a/web/projects/shared/src/i18n/dictionaries/fr.ts b/web/projects/shared/src/i18n/dictionaries/fr.ts
index 83fe4f543..fdc31c417 100644
--- a/web/projects/shared/src/i18n/dictionaries/fr.ts
+++ b/web/projects/shared/src/i18n/dictionaries/fr.ts
@@ -99,6 +99,7 @@ export default {
101: 'Vous avez des modifications non enregistrées. Voulez-vous vraiment quitter ?',
102: 'Quitter',
103: 'Êtes-vous sûr ?',
+ 104: 'Nouvelle passerelle réseau',
108: 'public',
109: 'privé',
111: 'Aucune domaine onion',
diff --git a/web/projects/shared/src/i18n/dictionaries/pl.ts b/web/projects/shared/src/i18n/dictionaries/pl.ts
index 53577081d..874a7a368 100644
--- a/web/projects/shared/src/i18n/dictionaries/pl.ts
+++ b/web/projects/shared/src/i18n/dictionaries/pl.ts
@@ -99,6 +99,7 @@ export default {
101: 'Masz niezapisane zmiany. Czy na pewno chcesz opuścić tę stronę?',
102: 'Opuść',
103: 'Czy jesteś pewien?',
+ 104: 'Nowa brama sieciowa',
108: 'publiczny',
109: 'prywatny',
111: 'Brak domeny onion',
diff --git a/web/projects/ui/src/app/app.providers.ts b/web/projects/ui/src/app/app.providers.ts
index edc8d0f4f..7528b2305 100644
--- a/web/projects/ui/src/app/app.providers.ts
+++ b/web/projects/ui/src/app/app.providers.ts
@@ -1,7 +1,7 @@
import { inject, provideAppInitializer } from '@angular/core'
import { UntypedFormBuilder } from '@angular/forms'
import { provideAnimations } from '@angular/platform-browser/animations'
-import { Router } from '@angular/router'
+import { ActivationStart, Router } from '@angular/router'
import { WA_LOCATION } from '@ng-web-apis/common'
import initArgon from '@start9labs/argon2'
import {
@@ -33,7 +33,7 @@ import {
TUI_DATE_VALUE_TRANSFORMER,
} from '@taiga-ui/kit'
import { PatchDB } from 'patch-db-client'
-import { filter, identity, of, pairwise } from 'rxjs'
+import { filter, identity, merge, of, pairwise } from 'rxjs'
import { ConfigService } from 'src/app/services/config.service'
import {
PATCH_CACHE,
@@ -116,11 +116,15 @@ export const APP_PROVIDERS = [
{
provide: TUI_DIALOGS_CLOSE,
useFactory: () =>
- inject(StateService).pipe(
- pairwise(),
- filter(
- ([prev, curr]) =>
- prev === 'running' && (curr === 'error' || curr === 'initializing'),
+ merge(
+ inject(Router).events.pipe(filter(e => e instanceof ActivationStart)),
+ inject(StateService).pipe(
+ pairwise(),
+ filter(
+ ([prev, curr]) =>
+ prev === 'running' &&
+ (curr === 'error' || curr === 'initializing'),
+ ),
),
),
},
diff --git a/web/projects/ui/src/app/routes/portal/components/form/controls/select.component.ts b/web/projects/ui/src/app/routes/portal/components/form/controls/select.component.ts
index 7c2bce126..de6af9ba0 100644
--- a/web/projects/ui/src/app/routes/portal/components/form/controls/select.component.ts
+++ b/web/projects/ui/src/app/routes/portal/components/form/controls/select.component.ts
@@ -1,5 +1,6 @@
import { Component, inject } from '@angular/core'
import { FormsModule } from '@angular/forms'
+import { Router, RouterLink } from '@angular/router'
import { invert } from '@start9labs/shared'
import { IST } from '@start9labs/start-sdk'
import { TUI_IS_MOBILE } from '@taiga-ui/cdk'
@@ -36,6 +37,7 @@ import { HintPipe } from '../pipes/hint.pipe'
[placeholder]="spec.name"
[items]="items"
[(ngModel)]="selected"
+ (ngModelChange)="onChange($event)"
>
} @else {
@for (item of items; track item) {
-
+ @if (inverted[item]?.startsWith('~')) {
+
+ {{ item }}
+
+ } @else {
+
+ }
}
}
@@ -70,6 +84,7 @@ import { HintPipe } from '../pipes/hint.pipe'
providers: [tuiFluidTypographyOptionsProvider({ max: 1 })],
imports: [
FormsModule,
+ RouterLink,
TuiTextfield,
TuiSelect,
TuiDataList,
@@ -81,8 +96,8 @@ import { HintPipe } from '../pipes/hint.pipe'
],
})
export class FormSelectComponent extends Control {
- private readonly inverted = invert(this.spec.values)
-
+ protected readonly router = inject(Router)
+ protected readonly inverted = invert(this.spec.values)
protected readonly mobile = inject(TUI_IS_MOBILE)
protected readonly items = Object.values(this.spec.values)
protected readonly disabledItemHandler = (item: string) =>
@@ -101,4 +116,12 @@ export class FormSelectComponent extends Control {
set selected(value: string | null) {
this.value = (value && this.inverted[value]) || null
}
+
+ protected onChange(value: string) {
+ const mapped = this.inverted[value]
+
+ if (typeof mapped === 'string' && mapped.startsWith('~')) {
+ this.router.navigate([mapped.slice(1)])
+ }
+ }
}
diff --git a/web/projects/ui/src/app/routes/portal/components/interfaces/public-domains/pd.service.ts b/web/projects/ui/src/app/routes/portal/components/interfaces/public-domains/pd.service.ts
index ef602aa7a..2991c8bf8 100644
--- a/web/projects/ui/src/app/routes/portal/components/interfaces/public-domains/pd.service.ts
+++ b/web/projects/ui/src/app/routes/portal/components/interfaces/public-domains/pd.service.ts
@@ -247,10 +247,10 @@ export class PublicDomainService {
),
values: gateways.reduce>(
(obj, gateway) => ({
- ...obj,
[gateway.id]: gateway.name || gateway.ipInfo.name,
+ ...obj,
}),
- {},
+ { '~/system/gateways': this.i18n.transform('New gateway') },
),
default: '',
disabled: gateways