mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 12:11:56 +00:00
mok ux, autofill device and pf forms, docss for st, docs for start-sdk
This commit is contained in:
@@ -1,31 +1,72 @@
|
||||
import { Component } from '@angular/core'
|
||||
import { Component, inject } from '@angular/core'
|
||||
import { i18nPipe } from '@start9labs/shared'
|
||||
import { TuiButton, TuiDialogContext, TuiIcon } from '@taiga-ui/core'
|
||||
import { injectContext } from '@taiga-ui/polymorpheus'
|
||||
import { StateService } from '../services/state.service'
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
imports: [TuiButton, TuiIcon, i18nPipe],
|
||||
template: `
|
||||
<div class="icon-container">
|
||||
<tui-icon icon="@tui.shield-check" class="mok-icon" />
|
||||
@if (!stateService.kiosk) {
|
||||
<div class="animation-container">
|
||||
<div class="port">
|
||||
<div class="port-inner"></div>
|
||||
</div>
|
||||
<div class="cable">
|
||||
<div class="cable-connector"></div>
|
||||
<div class="cable-body"></div>
|
||||
</div>
|
||||
</div>
|
||||
<p>
|
||||
{{
|
||||
'Connect a monitor and keyboard to your server before rebooting.'
|
||||
| i18n
|
||||
}}
|
||||
</p>
|
||||
} @else {
|
||||
<div class="icon-container">
|
||||
<tui-icon icon="@tui.monitor" class="monitor-icon" />
|
||||
</div>
|
||||
<p>
|
||||
{{ 'Keep your monitor connected for the next reboot.' | i18n }}
|
||||
</p>
|
||||
}
|
||||
|
||||
<div class="mok-info">
|
||||
<p>
|
||||
{{
|
||||
'Your system has Secure Boot enabled, which requires all kernel modules to be signed with a trusted key. Some hardware drivers — such as those for NVIDIA GPUs — are not signed by the default distribution key. Enrolling the StartOS signing key allows your firmware to trust these modules so your hardware can be fully utilized.'
|
||||
| i18n
|
||||
}}
|
||||
</p>
|
||||
<p>
|
||||
{{
|
||||
'On the next boot, a blue screen (MokManager) will appear. You will have 10 seconds to select "Enroll MOK" before it dismisses.'
|
||||
| i18n
|
||||
}}
|
||||
</p>
|
||||
<p>
|
||||
{{
|
||||
'If you miss the window, simply reboot to try again. The blue screen will appear on every boot until the key is enrolled.'
|
||||
| i18n
|
||||
}}
|
||||
</p>
|
||||
<p class="steps-label">
|
||||
{{ 'After clicking "Enroll MOK":' | i18n }}
|
||||
</p>
|
||||
<ol>
|
||||
<li>Click "Continue"</li>
|
||||
<li>
|
||||
{{ 'When prompted, enter your StartOS password' | i18n }}
|
||||
</li>
|
||||
<li>Click "Reboot"</li>
|
||||
</ol>
|
||||
</div>
|
||||
<h3>{{ 'Secure Boot Key Enrollment' | i18n }}</h3>
|
||||
<p>
|
||||
{{
|
||||
'A signing key was enrolled for Secure Boot. On the next reboot, a blue screen (MokManager) will appear.'
|
||||
| i18n
|
||||
}}
|
||||
</p>
|
||||
<ol>
|
||||
<li>Select "Enroll MOK"</li>
|
||||
<li>Select "Continue"</li>
|
||||
<li>{{ 'Enter your StartOS master password when prompted' | i18n }}</li>
|
||||
<li>Select "Reboot"</li>
|
||||
</ol>
|
||||
|
||||
<footer>
|
||||
<button tuiButton (click)="context.completeWith(true)">
|
||||
{{ 'Got it' | i18n }}
|
||||
{{ 'Ok' | i18n }}
|
||||
</button>
|
||||
</footer>
|
||||
`,
|
||||
@@ -41,29 +82,114 @@ import { injectContext } from '@taiga-ui/polymorpheus'
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.mok-icon {
|
||||
.monitor-icon {
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
color: var(--tui-status-info);
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0 0 0.5rem;
|
||||
.animation-container {
|
||||
position: relative;
|
||||
width: 160px;
|
||||
height: 69px;
|
||||
}
|
||||
|
||||
.port {
|
||||
position: absolute;
|
||||
left: 20px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 28px;
|
||||
height: 18px;
|
||||
background: var(--tui-background-neutral-1);
|
||||
border: 2px solid var(--tui-border-normal);
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.port-inner {
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
left: 3px;
|
||||
right: 3px;
|
||||
bottom: 3px;
|
||||
background: var(--tui-background-neutral-2);
|
||||
border-radius: 1px;
|
||||
}
|
||||
|
||||
.cable {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
animation: slide-in 2s ease-in-out 0.5s infinite;
|
||||
left: 130px;
|
||||
}
|
||||
|
||||
.cable-connector {
|
||||
width: 18px;
|
||||
height: 12px;
|
||||
background: var(--tui-text-secondary);
|
||||
border-radius: 1px;
|
||||
}
|
||||
|
||||
.cable-body {
|
||||
width: 50px;
|
||||
height: 6px;
|
||||
background: var(--tui-text-tertiary);
|
||||
border-radius: 0 3px 3px 0;
|
||||
}
|
||||
|
||||
@keyframes slide-in {
|
||||
0% {
|
||||
left: 130px;
|
||||
opacity: 0;
|
||||
}
|
||||
5% {
|
||||
left: 130px;
|
||||
opacity: 1;
|
||||
}
|
||||
60% {
|
||||
left: 32px;
|
||||
opacity: 1;
|
||||
}
|
||||
80% {
|
||||
left: 32px;
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
left: 32px;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.mok-info {
|
||||
text-align: left;
|
||||
margin-top: 0.5rem;
|
||||
|
||||
p {
|
||||
margin: 0 0 0.75rem;
|
||||
color: var(--tui-text-secondary);
|
||||
}
|
||||
|
||||
.steps-label {
|
||||
margin-bottom: 0.25rem;
|
||||
font-weight: 500;
|
||||
color: var(--tui-text-primary);
|
||||
}
|
||||
|
||||
ol {
|
||||
margin: 0 0 1rem;
|
||||
padding-left: 1.5rem;
|
||||
|
||||
li {
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0 0 1rem;
|
||||
color: var(--tui-text-secondary);
|
||||
}
|
||||
|
||||
ol {
|
||||
text-align: left;
|
||||
margin: 0 0 1.5rem;
|
||||
padding-left: 1.5rem;
|
||||
|
||||
li {
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
footer {
|
||||
@@ -74,4 +200,5 @@ import { injectContext } from '@taiga-ui/polymorpheus'
|
||||
})
|
||||
export class MokEnrollmentDialog {
|
||||
protected readonly context = injectContext<TuiDialogContext<boolean>>()
|
||||
readonly stateService = inject(StateService)
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import {
|
||||
AfterViewInit,
|
||||
Component,
|
||||
DOCUMENT,
|
||||
ElementRef,
|
||||
inject,
|
||||
ViewChild,
|
||||
DOCUMENT,
|
||||
} from '@angular/core'
|
||||
import {
|
||||
DialogService,
|
||||
@@ -12,17 +12,17 @@ import {
|
||||
ErrorService,
|
||||
i18nPipe,
|
||||
} from '@start9labs/shared'
|
||||
import { T } from '@start9labs/start-sdk'
|
||||
import { TuiIcon, TuiLoader, TuiTitle } from '@taiga-ui/core'
|
||||
import { TuiAvatar } from '@taiga-ui/kit'
|
||||
import { TuiCardLarge, TuiCell, TuiHeader } from '@taiga-ui/layout'
|
||||
import { ApiService } from '../services/api.service'
|
||||
import { StateService } from '../services/state.service'
|
||||
import { PolymorpheusComponent } from '@taiga-ui/polymorpheus'
|
||||
import { DocumentationComponent } from '../components/documentation.component'
|
||||
import { MatrixComponent } from '../components/matrix.component'
|
||||
import { MokEnrollmentDialog } from '../components/mok-enrollment.dialog'
|
||||
import { RemoveMediaDialog } from '../components/remove-media.dialog'
|
||||
import { T } from '@start9labs/start-sdk'
|
||||
import { PolymorpheusComponent } from '@taiga-ui/polymorpheus'
|
||||
import { ApiService } from '../services/api.service'
|
||||
import { StateService } from '../services/state.service'
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
@@ -50,7 +50,7 @@ import { PolymorpheusComponent } from '@taiga-ui/polymorpheus'
|
||||
} @else {
|
||||
<!-- Step: Download Address Info (non-kiosk only) -->
|
||||
@if (!stateService.kiosk) {
|
||||
<button tuiCell="l" [disabled]="downloaded" (click)="download()">
|
||||
<button tuiCell="l" (click)="download()">
|
||||
<tui-avatar appearance="secondary" src="@tui.download" />
|
||||
<div tuiTitle>
|
||||
{{ 'Download Address Info' | i18n }}
|
||||
@@ -67,12 +67,12 @@ import { PolymorpheusComponent } from '@taiga-ui/polymorpheus'
|
||||
</button>
|
||||
}
|
||||
|
||||
<!-- Step: Remove USB Media (when restart needed) -->
|
||||
<!-- Step: Restart flow -->
|
||||
@if (result.needsRestart) {
|
||||
<button
|
||||
tuiCell="l"
|
||||
[class.disabled]="!stateService.kiosk && !downloaded"
|
||||
[disabled]="(!stateService.kiosk && !downloaded) || usbRemoved"
|
||||
[disabled]="!stateService.kiosk && !downloaded"
|
||||
(click)="removeMedia()"
|
||||
>
|
||||
<tui-avatar appearance="secondary" src="@tui.usb" />
|
||||
@@ -90,11 +90,39 @@ import { PolymorpheusComponent } from '@taiga-ui/polymorpheus'
|
||||
}
|
||||
</button>
|
||||
|
||||
<!-- Step: Secure Boot Enrollment (when MOK enrolled) -->
|
||||
@if (stateService.mokEnrolled) {
|
||||
<button
|
||||
tuiCell="l"
|
||||
[class.disabled]="!usbRemoved"
|
||||
[disabled]="!usbRemoved"
|
||||
(click)="acknowledgeMok()"
|
||||
>
|
||||
<tui-avatar appearance="secondary" src="@tui.shield-check" />
|
||||
<div tuiTitle>
|
||||
{{ 'Secure Boot Enrollment' | i18n }}
|
||||
<div tuiSubtitle>
|
||||
{{
|
||||
'Prepare for Secure Boot key enrollment on the next reboot'
|
||||
| i18n
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
@if (mokAcknowledged) {
|
||||
<tui-icon icon="@tui.circle-check" class="g-positive" />
|
||||
}
|
||||
</button>
|
||||
}
|
||||
|
||||
<!-- Step: Restart Server -->
|
||||
<button
|
||||
tuiCell="l"
|
||||
[class.disabled]="!usbRemoved"
|
||||
[disabled]="!usbRemoved || rebooted || rebooting"
|
||||
[class.disabled]="
|
||||
!usbRemoved || (stateService.mokEnrolled && !mokAcknowledged)
|
||||
"
|
||||
[disabled]="
|
||||
!usbRemoved || (stateService.mokEnrolled && !mokAcknowledged)
|
||||
"
|
||||
(click)="reboot()"
|
||||
>
|
||||
<tui-avatar appearance="secondary" src="@tui.rotate-cw" />
|
||||
@@ -116,6 +144,16 @@ import { PolymorpheusComponent } from '@taiga-ui/polymorpheus'
|
||||
<tui-icon icon="@tui.circle-check" class="g-positive" />
|
||||
}
|
||||
</button>
|
||||
} @else if (stateService.kiosk) {
|
||||
<button tuiCell="l" (click)="exitKiosk()">
|
||||
<tui-avatar appearance="secondary" src="@tui.log-in" />
|
||||
<div tuiTitle>
|
||||
{{ 'Continue to Login' | i18n }}
|
||||
<div tuiSubtitle>
|
||||
{{ 'Proceed to the StartOS login screen' | i18n }}
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
}
|
||||
|
||||
<!-- Step: Open Local Address (non-kiosk only) -->
|
||||
@@ -137,22 +175,6 @@ import { PolymorpheusComponent } from '@taiga-ui/polymorpheus'
|
||||
}
|
||||
|
||||
<!-- Step: Continue to Login (kiosk only) -->
|
||||
@if (stateService.kiosk) {
|
||||
<button
|
||||
tuiCell="l"
|
||||
[class.disabled]="result.needsRestart && !rebooted"
|
||||
[disabled]="result.needsRestart && !rebooted"
|
||||
(click)="exitKiosk()"
|
||||
>
|
||||
<tui-avatar appearance="secondary" src="@tui.log-in" />
|
||||
<div tuiTitle>
|
||||
{{ 'Continue to Login' | i18n }}
|
||||
<div tuiSubtitle>
|
||||
{{ 'Proceed to the StartOS login screen' | i18n }}
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
}
|
||||
}
|
||||
</section>
|
||||
`,
|
||||
@@ -198,6 +220,7 @@ export default class SuccessPage implements AfterViewInit {
|
||||
lanAddress = ''
|
||||
downloaded = false
|
||||
usbRemoved = false
|
||||
mokAcknowledged = false
|
||||
rebooting = false
|
||||
rebooted = false
|
||||
|
||||
@@ -212,8 +235,6 @@ export default class SuccessPage implements AfterViewInit {
|
||||
}
|
||||
|
||||
download() {
|
||||
if (this.downloaded) return
|
||||
|
||||
const lanElem = this.document.getElementById('lan-addr')
|
||||
if (lanElem) lanElem.innerHTML = this.lanAddress
|
||||
|
||||
@@ -243,6 +264,19 @@ export default class SuccessPage implements AfterViewInit {
|
||||
})
|
||||
}
|
||||
|
||||
acknowledgeMok() {
|
||||
this.dialogs
|
||||
.openComponent<boolean>(new PolymorpheusComponent(MokEnrollmentDialog), {
|
||||
label: 'Secure Boot',
|
||||
size: 'm',
|
||||
dismissible: false,
|
||||
closeable: false,
|
||||
})
|
||||
.subscribe(() => {
|
||||
this.mokAcknowledged = true
|
||||
})
|
||||
}
|
||||
|
||||
exitKiosk() {
|
||||
this.api.exit()
|
||||
}
|
||||
@@ -252,6 +286,8 @@ export default class SuccessPage implements AfterViewInit {
|
||||
}
|
||||
|
||||
async reboot() {
|
||||
if (this.rebooting || this.rebooted) return
|
||||
|
||||
this.rebooting = true
|
||||
|
||||
try {
|
||||
@@ -276,20 +312,6 @@ export default class SuccessPage implements AfterViewInit {
|
||||
await this.api.exit()
|
||||
}
|
||||
}
|
||||
|
||||
if (this.stateService.mokEnrolled && this.result.needsRestart) {
|
||||
this.dialogs
|
||||
.openComponent<boolean>(
|
||||
new PolymorpheusComponent(MokEnrollmentDialog),
|
||||
{
|
||||
label: 'Secure Boot',
|
||||
size: 's',
|
||||
dismissible: false,
|
||||
closeable: true,
|
||||
},
|
||||
)
|
||||
.subscribe()
|
||||
}
|
||||
} catch (e: any) {
|
||||
this.errorService.handleError(e)
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ export class MockApiService extends ApiService {
|
||||
return {
|
||||
guid: 'mock-data-guid',
|
||||
attach: !params.dataDrive.wipe,
|
||||
mokEnrolled: false,
|
||||
mokEnrolled: true,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -713,4 +713,13 @@ export default {
|
||||
790: 'Ein Signaturschlüssel wurde für Secure Boot registriert. Beim nächsten Neustart erscheint ein blauer Bildschirm (MokManager).',
|
||||
791: 'Geben Sie Ihr StartOS-Master-Passwort ein, wenn Sie dazu aufgefordert werden',
|
||||
792: 'Verstanden',
|
||||
793: 'Secure-Boot-Registrierung',
|
||||
794: 'Vorbereitung auf die Secure-Boot-Schlüsselregistrierung beim nächsten Neustart',
|
||||
795: 'Schließen Sie vor dem Neustart einen Monitor und eine Tastatur an Ihren Server an.',
|
||||
796: 'Lassen Sie Ihren Monitor für den nächsten Neustart angeschlossen.',
|
||||
797: 'Beim nächsten Start erscheint ein blauer Bildschirm (MokManager). Sie haben 10 Sekunden, um "Enroll MOK" auszuwählen, bevor er verschwindet.',
|
||||
798: 'Falls Sie das Zeitfenster verpassen, starten Sie einfach neu und versuchen Sie es erneut. Der blaue Bildschirm erscheint bei jedem Start, bis der Schlüssel registriert ist.',
|
||||
799: 'Nach Klick auf "Enroll MOK":',
|
||||
800: 'Geben Sie bei Aufforderung Ihr StartOS-Passwort ein',
|
||||
801: 'Ihr System hat Secure Boot aktiviert, was erfordert, dass alle Kernel-Module mit einem vertrauenswürdigen Schlüssel signiert sind. Einige Hardware-Treiber \u2014 wie die für NVIDIA-GPUs \u2014 sind nicht mit dem Standard-Distributionsschlüssel signiert. Die Registrierung des StartOS-Signaturschlüssels ermöglicht es Ihrer Firmware, diesen Modulen zu vertrauen, damit Ihre Hardware vollständig genutzt werden kann.',
|
||||
} satisfies i18n
|
||||
|
||||
@@ -714,4 +714,13 @@ export const ENGLISH: Record<string, number> = {
|
||||
'A signing key was enrolled for Secure Boot. On the next reboot, a blue screen (MokManager) will appear.': 790,
|
||||
'Enter your StartOS master password when prompted': 791,
|
||||
'Got it': 792,
|
||||
'Secure Boot Enrollment': 793,
|
||||
'Prepare for Secure Boot key enrollment on the next reboot': 794,
|
||||
'Connect a monitor and keyboard to your server before rebooting.': 795,
|
||||
'Keep your monitor connected for the next reboot.': 796,
|
||||
'On the next boot, a blue screen (MokManager) will appear. You will have 10 seconds to select "Enroll MOK" before it dismisses.': 797,
|
||||
'If you miss the window, simply reboot to try again. The blue screen will appear on every boot until the key is enrolled.': 798,
|
||||
'After clicking "Enroll MOK":': 799,
|
||||
'When prompted, enter your StartOS password': 800,
|
||||
'Your system has Secure Boot enabled, which requires all kernel modules to be signed with a trusted key. Some hardware drivers \u2014 such as those for NVIDIA GPUs \u2014 are not signed by the default distribution key. Enrolling the StartOS signing key allows your firmware to trust these modules so your hardware can be fully utilized.': 801,
|
||||
}
|
||||
|
||||
@@ -713,4 +713,13 @@ export default {
|
||||
790: 'Se registró una clave de firma para Secure Boot. En el próximo reinicio, aparecerá una pantalla azul (MokManager).',
|
||||
791: 'Ingrese su contraseña maestra de StartOS cuando se le solicite',
|
||||
792: 'Entendido',
|
||||
793: 'Registro de Secure Boot',
|
||||
794: 'Prepararse para el registro de clave de Secure Boot en el próximo reinicio',
|
||||
795: 'Conecte un monitor y un teclado a su servidor antes de reiniciar.',
|
||||
796: 'Mantenga su monitor conectado para el próximo reinicio.',
|
||||
797: 'En el próximo arranque, aparecerá una pantalla azul (MokManager). Tendrá 10 segundos para seleccionar "Enroll MOK" antes de que desaparezca.',
|
||||
798: 'Si pierde la oportunidad, simplemente reinicie para intentar de nuevo. La pantalla azul aparecerá en cada arranque hasta que se registre la clave.',
|
||||
799: 'Después de hacer clic en "Enroll MOK":',
|
||||
800: 'Cuando se le solicite, ingrese su contraseña de StartOS',
|
||||
801: 'Su sistema tiene Secure Boot habilitado, lo que requiere que todos los módulos del kernel estén firmados con una clave de confianza. Algunos controladores de hardware \u2014 como los de las GPU NVIDIA \u2014 no están firmados con la clave de distribución predeterminada. Registrar la clave de firma de StartOS permite que su firmware confíe en estos módulos para que su hardware pueda utilizarse completamente.',
|
||||
} satisfies i18n
|
||||
|
||||
@@ -709,8 +709,17 @@ export default {
|
||||
786: 'Automatique',
|
||||
787: 'Trafic sortant',
|
||||
788: 'Utiliser la passerelle',
|
||||
789: "Enregistrement de la clé Secure Boot",
|
||||
790: "Une clé de signature a été enregistrée pour Secure Boot. Au prochain redémarrage, un écran bleu (MokManager) apparaîtra.",
|
||||
789: 'Enregistrement de la clé Secure Boot',
|
||||
790: 'Une clé de signature a été enregistrée pour Secure Boot. Au prochain redémarrage, un écran bleu (MokManager) apparaîtra.',
|
||||
791: 'Entrez votre mot de passe principal StartOS lorsque vous y êtes invité',
|
||||
792: 'Compris',
|
||||
793: 'Enregistrement Secure Boot',
|
||||
794: "Préparez-vous à l'enregistrement de la clé Secure Boot au prochain redémarrage",
|
||||
795: 'Connectez un moniteur et un clavier à votre serveur avant de redémarrer.',
|
||||
796: 'Gardez votre moniteur connecté pour le prochain redémarrage.',
|
||||
797: 'Au prochain démarrage, un écran bleu (MokManager) apparaîtra. Vous aurez 10 secondes pour sélectionner "Enroll MOK" avant qu\'il ne disparaisse.',
|
||||
798: "Si vous manquez la fenêtre, redémarrez simplement pour réessayer. L'écran bleu apparaîtra à chaque démarrage jusqu'à ce que la clé soit enregistrée.",
|
||||
799: 'Après avoir cliqué sur "Enroll MOK" :',
|
||||
800: 'Lorsque vous y êtes invité, entrez votre mot de passe StartOS',
|
||||
801: "Votre système a Secure Boot activé, ce qui exige que tous les modules du noyau soient signés avec une clé de confiance. Certains pilotes matériels \u2014 comme ceux des GPU NVIDIA \u2014 ne sont pas signés par la clé de distribution par défaut. L'enregistrement de la clé de signature StartOS permet à votre firmware de faire confiance à ces modules afin que votre matériel puisse être pleinement utilisé.",
|
||||
} satisfies i18n
|
||||
|
||||
@@ -713,4 +713,13 @@ export default {
|
||||
790: 'Klucz podpisu został zarejestrowany dla Secure Boot. Przy następnym uruchomieniu pojawi się niebieski ekran (MokManager).',
|
||||
791: 'Wprowadź swoje hasło główne StartOS po wyświetleniu monitu',
|
||||
792: 'Rozumiem',
|
||||
793: 'Rejestracja Secure Boot',
|
||||
794: 'Przygotuj się do rejestracji klucza Secure Boot przy następnym uruchomieniu',
|
||||
795: 'Podłącz monitor i klawiaturę do serwera przed ponownym uruchomieniem.',
|
||||
796: 'Pozostaw monitor podłączony do następnego uruchomienia.',
|
||||
797: 'Przy następnym uruchomieniu pojawi się niebieski ekran (MokManager). Będziesz mieć 10 sekund na wybranie "Enroll MOK", zanim zniknie.',
|
||||
798: 'Jeśli przegapisz okno, po prostu uruchom ponownie i spróbuj jeszcze raz. Niebieski ekran będzie pojawiał się przy każdym uruchomieniu, dopóki klucz nie zostanie zarejestrowany.',
|
||||
799: 'Po kliknięciu "Enroll MOK":',
|
||||
800: 'Po wyświetleniu monitu wprowadź swoje hasło StartOS',
|
||||
801: 'Twój system ma włączony Secure Boot, co wymaga, aby wszystkie moduły jądra były podpisane zaufanym kluczem. Niektóre sterowniki sprzętowe \u2014 takie jak te dla GPU NVIDIA \u2014 nie są podpisane domyślnym kluczem dystrybucji. Zarejestrowanie klucza podpisu StartOS pozwala firmware ufać tym modułom, aby sprzęt mógł być w pełni wykorzystany.',
|
||||
} satisfies i18n
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
Validators,
|
||||
} from '@angular/forms'
|
||||
import { ErrorService, LoadingService } from '@start9labs/shared'
|
||||
import { utils } from '@start9labs/start-sdk'
|
||||
import {
|
||||
TUI_IS_MOBILE,
|
||||
TuiAutoFocus,
|
||||
@@ -121,15 +120,23 @@ export class DevicesAdd {
|
||||
protected readonly context =
|
||||
injectContext<TuiDialogContext<void, DeviceData>>()
|
||||
|
||||
private readonly autoSubnet =
|
||||
!this.context.data.device && this.context.data.subnets().length === 1
|
||||
? this.context.data.subnets().at(0)
|
||||
: undefined
|
||||
|
||||
protected readonly form = inject(NonNullableFormBuilder).group({
|
||||
name: [this.context.data.device?.name || '', Validators.required],
|
||||
subnet: [
|
||||
this.context.data.device?.subnet,
|
||||
this.context.data.device?.subnet ?? this.autoSubnet,
|
||||
[Validators.required, subnetValidator],
|
||||
],
|
||||
ip: [
|
||||
this.context.data.device?.ip || '',
|
||||
[Validators.required, Validators.pattern(utils.Patterns.ipv4.regex)],
|
||||
this.context.data.device?.ip ||
|
||||
(this.autoSubnet ? getIp(this.autoSubnet) : ''),
|
||||
this.autoSubnet
|
||||
? [Validators.required, ipInSubnetValidator(this.autoSubnet.range)]
|
||||
: [],
|
||||
],
|
||||
})
|
||||
|
||||
|
||||
@@ -22,10 +22,10 @@ import {
|
||||
TuiCheckbox,
|
||||
TuiChevron,
|
||||
TuiDataListWrapper,
|
||||
TuiElasticContainer,
|
||||
TuiFieldErrorPipe,
|
||||
TuiInputNumber,
|
||||
TuiSelect,
|
||||
TuiElasticContainer,
|
||||
} from '@taiga-ui/kit'
|
||||
import { TuiForm } from '@taiga-ui/layout'
|
||||
import { injectContext, PolymorpheusComponent } from '@taiga-ui/polymorpheus'
|
||||
@@ -167,7 +167,12 @@ export class PortForwardsAdd {
|
||||
|
||||
protected readonly form = inject(NonNullableFormBuilder).group({
|
||||
label: ['', Validators.required],
|
||||
externalip: ['', Validators.required],
|
||||
externalip: [
|
||||
this.context.data.ips().length === 1
|
||||
? (this.context.data.ips().at(0) ?? '')
|
||||
: '',
|
||||
Validators.required,
|
||||
],
|
||||
externalport: [null as number | null, Validators.required],
|
||||
device: [null as MappedDevice | null, Validators.required],
|
||||
internalport: [null as number | null, Validators.required],
|
||||
|
||||
@@ -16,6 +16,6 @@ export interface MappedForward {
|
||||
}
|
||||
|
||||
export interface PortForwardsData {
|
||||
readonly ips: Signal<any>
|
||||
readonly ips: Signal<readonly string[]>
|
||||
readonly devices: Signal<readonly MappedDevice[]>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user