mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 12:11:56 +00:00
fixes #3150
This commit is contained in:
@@ -4,8 +4,16 @@ import {
|
|||||||
HostListener,
|
HostListener,
|
||||||
inject,
|
inject,
|
||||||
} from '@angular/core'
|
} from '@angular/core'
|
||||||
|
import {
|
||||||
|
AbstractControl,
|
||||||
|
FormControl,
|
||||||
|
FormGroup,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
ValidatorFn,
|
||||||
|
Validators,
|
||||||
|
} from '@angular/forms'
|
||||||
import { Router } from '@angular/router'
|
import { Router } from '@angular/router'
|
||||||
import { FormsModule } from '@angular/forms'
|
import { WA_IS_MOBILE } from '@ng-web-apis/platform'
|
||||||
import {
|
import {
|
||||||
DialogService,
|
DialogService,
|
||||||
DiskInfo,
|
DiskInfo,
|
||||||
@@ -14,13 +22,14 @@ import {
|
|||||||
i18nPipe,
|
i18nPipe,
|
||||||
toGuid,
|
toGuid,
|
||||||
} from '@start9labs/shared'
|
} from '@start9labs/shared'
|
||||||
import { WA_IS_MOBILE } from '@ng-web-apis/platform'
|
import { TuiMapperPipe, TuiValidator } from '@taiga-ui/cdk'
|
||||||
import {
|
import {
|
||||||
TuiButton,
|
TuiButton,
|
||||||
|
TuiError,
|
||||||
TuiIcon,
|
TuiIcon,
|
||||||
TuiLoader,
|
TuiLoader,
|
||||||
TuiInput,
|
|
||||||
TuiNotification,
|
TuiNotification,
|
||||||
|
TUI_VALIDATION_ERRORS,
|
||||||
TuiTitle,
|
TuiTitle,
|
||||||
} from '@taiga-ui/core'
|
} from '@taiga-ui/core'
|
||||||
import {
|
import {
|
||||||
@@ -29,49 +38,55 @@ import {
|
|||||||
TuiSelect,
|
TuiSelect,
|
||||||
TuiTooltip,
|
TuiTooltip,
|
||||||
} from '@taiga-ui/kit'
|
} from '@taiga-ui/kit'
|
||||||
import { TuiCardLarge, TuiHeader } from '@taiga-ui/layout'
|
import { TuiCardLarge, TuiForm, TuiHeader } from '@taiga-ui/layout'
|
||||||
import { PolymorpheusComponent } from '@taiga-ui/polymorpheus'
|
import { distinctUntilChanged, filter, Subscription } from 'rxjs'
|
||||||
import { filter, Subscription } from 'rxjs'
|
import { PRESERVE_OVERWRITE } from '../components/preserve-overwrite.dialog'
|
||||||
import { ApiService } from '../services/api.service'
|
import { ApiService } from '../services/api.service'
|
||||||
import { StateService } from '../services/state.service'
|
import { StateService } from '../services/state.service'
|
||||||
import { PRESERVE_OVERWRITE } from '../components/preserve-overwrite.dialog'
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
template: `
|
template: `
|
||||||
@if (!shuttingDown) {
|
@if (!shuttingDown) {
|
||||||
<section tuiCardLarge="compact">
|
@if (loading) {
|
||||||
<header tuiHeader>
|
<section tuiCardLarge="compact">
|
||||||
<h2 tuiTitle>{{ 'Select Drives' | i18n }}</h2>
|
<header tuiHeader>
|
||||||
</header>
|
<h2 tuiTitle>{{ 'Select Drives' | i18n }}</h2>
|
||||||
|
</header>
|
||||||
@if (loading) {
|
|
||||||
<tui-loader />
|
<tui-loader />
|
||||||
} @else if (drives.length === 0) {
|
</section>
|
||||||
|
} @else if (drives.length === 0) {
|
||||||
|
<section tuiCardLarge="compact">
|
||||||
|
<header tuiHeader>
|
||||||
|
<h2 tuiTitle>{{ 'Select Drives' | i18n }}</h2>
|
||||||
|
</header>
|
||||||
<p tuiNotification size="m" appearance="warning">
|
<p tuiNotification size="m" appearance="warning">
|
||||||
{{
|
{{
|
||||||
'No drives found. Please connect a drive and click Refresh.'
|
'No drives found. Please connect a drive and click Refresh.'
|
||||||
| i18n
|
| i18n
|
||||||
}}
|
}}
|
||||||
</p>
|
</p>
|
||||||
} @else {
|
<footer>
|
||||||
<tui-textfield
|
<button tuiButton appearance="secondary" (click)="refresh()">
|
||||||
[stringify]="stringify"
|
{{ 'Refresh' | i18n }}
|
||||||
[disabledItemHandler]="osDisabled"
|
</button>
|
||||||
>
|
</footer>
|
||||||
|
</section>
|
||||||
|
} @else {
|
||||||
|
<form tuiCardLarge="compact" tuiForm [formGroup]="form">
|
||||||
|
<header tuiHeader>
|
||||||
|
<h2 tuiTitle>{{ 'Select Drives' | i18n }}</h2>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<tui-textfield [stringify]="stringify">
|
||||||
<label tuiLabel>{{ 'OS Drive' | i18n }}</label>
|
<label tuiLabel>{{ 'OS Drive' | i18n }}</label>
|
||||||
@if (mobile) {
|
@if (mobile) {
|
||||||
<select
|
<select
|
||||||
tuiSelect
|
tuiSelect
|
||||||
[ngModel]="selectedOsDrive"
|
formControlName="osDrive"
|
||||||
(ngModelChange)="onOsDriveChange($event)"
|
|
||||||
[items]="drives"
|
[items]="drives"
|
||||||
></select>
|
></select>
|
||||||
} @else {
|
} @else {
|
||||||
<input
|
<input tuiSelect formControlName="osDrive" />
|
||||||
tuiSelect
|
|
||||||
[ngModel]="selectedOsDrive"
|
|
||||||
(ngModelChange)="onOsDriveChange($event)"
|
|
||||||
/>
|
|
||||||
}
|
}
|
||||||
@if (!mobile) {
|
@if (!mobile) {
|
||||||
<tui-data-list-wrapper
|
<tui-data-list-wrapper
|
||||||
@@ -82,24 +97,28 @@ import { PRESERVE_OVERWRITE } from '../components/preserve-overwrite.dialog'
|
|||||||
}
|
}
|
||||||
<tui-icon [tuiTooltip]="osDriveTooltip" />
|
<tui-icon [tuiTooltip]="osDriveTooltip" />
|
||||||
</tui-textfield>
|
</tui-textfield>
|
||||||
|
@if (form.controls.osDrive.touched && form.controls.osDrive.invalid) {
|
||||||
|
<tui-error formControlName="osDrive" />
|
||||||
|
}
|
||||||
|
|
||||||
<tui-textfield
|
<tui-textfield [stringify]="stringify">
|
||||||
[stringify]="stringify"
|
|
||||||
[disabledItemHandler]="dataDisabled"
|
|
||||||
>
|
|
||||||
<label tuiLabel>{{ 'Data Drive' | i18n }}</label>
|
<label tuiLabel>{{ 'Data Drive' | i18n }}</label>
|
||||||
@if (mobile) {
|
@if (mobile) {
|
||||||
<select
|
<select
|
||||||
tuiSelect
|
tuiSelect
|
||||||
[(ngModel)]="selectedDataDrive"
|
formControlName="dataDrive"
|
||||||
(ngModelChange)="onDataDriveChange($event)"
|
|
||||||
[items]="drives"
|
[items]="drives"
|
||||||
|
[tuiValidator]="
|
||||||
|
form.controls.osDrive.value | tuiMapper: dataValidator
|
||||||
|
"
|
||||||
></select>
|
></select>
|
||||||
} @else {
|
} @else {
|
||||||
<input
|
<input
|
||||||
tuiSelect
|
tuiSelect
|
||||||
[(ngModel)]="selectedDataDrive"
|
formControlName="dataDrive"
|
||||||
(ngModelChange)="onDataDriveChange($event)"
|
[tuiValidator]="
|
||||||
|
form.controls.osDrive.value | tuiMapper: dataValidator
|
||||||
|
"
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
@if (!mobile) {
|
@if (!mobile) {
|
||||||
@@ -117,6 +136,11 @@ import { PRESERVE_OVERWRITE } from '../components/preserve-overwrite.dialog'
|
|||||||
}
|
}
|
||||||
<tui-icon [tuiTooltip]="dataDriveTooltip" />
|
<tui-icon [tuiTooltip]="dataDriveTooltip" />
|
||||||
</tui-textfield>
|
</tui-textfield>
|
||||||
|
@if (
|
||||||
|
form.controls.dataDrive.touched && form.controls.dataDrive.invalid
|
||||||
|
) {
|
||||||
|
<tui-error formControlName="dataDrive" />
|
||||||
|
}
|
||||||
|
|
||||||
<ng-template #driveContent let-drive>
|
<ng-template #driveContent let-drive>
|
||||||
<span tuiTitle>
|
<span tuiTitle>
|
||||||
@@ -126,24 +150,14 @@ import { PRESERVE_OVERWRITE } from '../components/preserve-overwrite.dialog'
|
|||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
}
|
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
@if (drives.length === 0) {
|
<button tuiButton [disabled]="form.invalid" (click)="continue()">
|
||||||
<button tuiButton appearance="secondary" (click)="refresh()">
|
|
||||||
{{ 'Refresh' | i18n }}
|
|
||||||
</button>
|
|
||||||
} @else {
|
|
||||||
<button
|
|
||||||
tuiButton
|
|
||||||
[disabled]="!selectedOsDrive || !selectedDataDrive"
|
|
||||||
(click)="continue()"
|
|
||||||
>
|
|
||||||
{{ 'Continue' | i18n }}
|
{{ 'Continue' | i18n }}
|
||||||
</button>
|
</button>
|
||||||
}
|
</footer>
|
||||||
</footer>
|
</form>
|
||||||
</section>
|
}
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
styles: `
|
styles: `
|
||||||
@@ -152,20 +166,34 @@ import { PRESERVE_OVERWRITE } from '../components/preserve-overwrite.dialog'
|
|||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
imports: [
|
imports: [
|
||||||
FormsModule,
|
ReactiveFormsModule,
|
||||||
TuiCardLarge,
|
TuiCardLarge,
|
||||||
|
TuiForm,
|
||||||
TuiButton,
|
TuiButton,
|
||||||
|
TuiError,
|
||||||
TuiIcon,
|
TuiIcon,
|
||||||
TuiLoader,
|
TuiLoader,
|
||||||
TuiInput,
|
|
||||||
TuiNotification,
|
TuiNotification,
|
||||||
TuiSelect,
|
TuiSelect,
|
||||||
TuiDataListWrapper,
|
TuiDataListWrapper,
|
||||||
TuiTooltip,
|
TuiTooltip,
|
||||||
|
TuiValidator,
|
||||||
|
TuiMapperPipe,
|
||||||
TuiHeader,
|
TuiHeader,
|
||||||
TuiTitle,
|
TuiTitle,
|
||||||
i18nPipe,
|
i18nPipe,
|
||||||
],
|
],
|
||||||
|
providers: [
|
||||||
|
{
|
||||||
|
provide: TUI_VALIDATION_ERRORS,
|
||||||
|
useFactory: () => {
|
||||||
|
const i18n = inject(i18nPipe)
|
||||||
|
return {
|
||||||
|
required: i18n.transform('Required'),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
})
|
})
|
||||||
export default class DrivesPage {
|
export default class DrivesPage {
|
||||||
private readonly api = inject(ApiService)
|
private readonly api = inject(ApiService)
|
||||||
@@ -188,29 +216,63 @@ export default class DrivesPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
readonly osDriveTooltip = this.i18n.transform(
|
readonly osDriveTooltip = this.i18n.transform(
|
||||||
'The drive where the StartOS operating system will be installed.',
|
'The drive where the StartOS operating system will be installed. Minimum 18 GB.',
|
||||||
)
|
)
|
||||||
readonly dataDriveTooltip = this.i18n.transform(
|
readonly dataDriveTooltip = this.i18n.transform(
|
||||||
'The drive where your StartOS data (services, settings, etc.) will be stored. This can be the same as the OS drive or a separate drive.',
|
'The drive where your StartOS data (services, settings, etc.) will be stored. This can be the same as the OS drive or a separate drive. Minimum 20 GB, or 38 GB if using a single drive for both OS and data.',
|
||||||
)
|
)
|
||||||
|
|
||||||
private readonly MIN_OS = 18 * 2 ** 30 // 18 GiB
|
private readonly MIN_OS = 18 * 2 ** 30 // 18 GiB
|
||||||
private readonly MIN_DATA = 20 * 2 ** 30 // 20 GiB
|
private readonly MIN_DATA = 20 * 2 ** 30 // 20 GiB
|
||||||
private readonly MIN_BOTH = 38 * 2 ** 30 // 38 GiB
|
private readonly MIN_BOTH = 38 * 2 ** 30 // 38 GiB
|
||||||
|
|
||||||
|
private readonly osCapacityValidator: ValidatorFn = ({
|
||||||
|
value,
|
||||||
|
}: AbstractControl) => {
|
||||||
|
if (!value) return null
|
||||||
|
return value.capacity < this.MIN_OS
|
||||||
|
? {
|
||||||
|
tooSmallOs: this.i18n.transform('OS drive must be at least 18 GB'),
|
||||||
|
}
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly form = new FormGroup({
|
||||||
|
osDrive: new FormControl<DiskInfo | null>(null, [
|
||||||
|
Validators.required,
|
||||||
|
this.osCapacityValidator,
|
||||||
|
]),
|
||||||
|
dataDrive: new FormControl<DiskInfo | null>(null, [Validators.required]),
|
||||||
|
})
|
||||||
|
|
||||||
|
readonly dataValidator =
|
||||||
|
(osDrive: DiskInfo | null): ValidatorFn =>
|
||||||
|
({ value }: AbstractControl) => {
|
||||||
|
if (!value) return null
|
||||||
|
const sameAsOs = osDrive && value.logicalname === osDrive.logicalname
|
||||||
|
const min = sameAsOs ? this.MIN_BOTH : this.MIN_DATA
|
||||||
|
if (value.capacity < min) {
|
||||||
|
return sameAsOs
|
||||||
|
? {
|
||||||
|
tooSmallBoth: this.i18n.transform(
|
||||||
|
'OS + data combined require at least 38 GB',
|
||||||
|
),
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
tooSmallData: this.i18n.transform(
|
||||||
|
'Data drive must be at least 20 GB',
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
drives: DiskInfo[] = []
|
drives: DiskInfo[] = []
|
||||||
loading = true
|
loading = true
|
||||||
shuttingDown = false
|
shuttingDown = false
|
||||||
private dialogSub?: Subscription
|
private dialogSub?: Subscription
|
||||||
selectedOsDrive: DiskInfo | null = null
|
|
||||||
selectedDataDrive: DiskInfo | null = null
|
|
||||||
preserveData: boolean | null = null
|
preserveData: boolean | null = null
|
||||||
|
|
||||||
readonly osDisabled = (drive: DiskInfo): boolean =>
|
|
||||||
drive.capacity < this.MIN_OS
|
|
||||||
|
|
||||||
dataDisabled = (drive: DiskInfo): boolean => drive.capacity < this.MIN_DATA
|
|
||||||
|
|
||||||
readonly driveName = (drive: DiskInfo): string =>
|
readonly driveName = (drive: DiskInfo): string =>
|
||||||
[drive.vendor, drive.model].filter(Boolean).join(' ') ||
|
[drive.vendor, drive.model].filter(Boolean).join(' ') ||
|
||||||
this.i18n.transform('Unknown Drive')
|
this.i18n.transform('Unknown Drive')
|
||||||
@@ -228,51 +290,40 @@ export default class DrivesPage {
|
|||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
await this.loadDrives()
|
await this.loadDrives()
|
||||||
|
|
||||||
|
this.form.controls.osDrive.valueChanges.subscribe(drive => {
|
||||||
|
if (drive) {
|
||||||
|
this.form.controls.osDrive.markAsTouched()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.form.controls.dataDrive.valueChanges
|
||||||
|
.pipe(distinctUntilChanged())
|
||||||
|
.subscribe(drive => {
|
||||||
|
this.preserveData = null
|
||||||
|
if (drive) {
|
||||||
|
this.form.controls.dataDrive.markAsTouched()
|
||||||
|
if (toGuid(drive)) {
|
||||||
|
this.showPreserveOverwriteDialog()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async refresh() {
|
async refresh() {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
this.selectedOsDrive = null
|
this.form.reset()
|
||||||
this.selectedDataDrive = null
|
|
||||||
this.preserveData = null
|
this.preserveData = null
|
||||||
await this.loadDrives()
|
await this.loadDrives()
|
||||||
}
|
}
|
||||||
|
|
||||||
onOsDriveChange(osDrive: DiskInfo | null) {
|
|
||||||
this.selectedOsDrive = osDrive
|
|
||||||
this.dataDisabled = (drive: DiskInfo) => {
|
|
||||||
if (osDrive && drive.logicalname === osDrive.logicalname) {
|
|
||||||
return drive.capacity < this.MIN_BOTH
|
|
||||||
}
|
|
||||||
return drive.capacity < this.MIN_DATA
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear data drive if it's now invalid
|
|
||||||
if (this.selectedDataDrive && this.dataDisabled(this.selectedDataDrive)) {
|
|
||||||
this.selectedDataDrive = null
|
|
||||||
this.preserveData = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onDataDriveChange(drive: DiskInfo | null) {
|
|
||||||
this.preserveData = null
|
|
||||||
|
|
||||||
if (!drive) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const hasStartOSData = !!toGuid(drive)
|
|
||||||
if (hasStartOSData) {
|
|
||||||
this.showPreserveOverwriteDialog()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
continue() {
|
continue() {
|
||||||
if (!this.selectedOsDrive || !this.selectedDataDrive) return
|
const osDrive = this.form.controls.osDrive.value
|
||||||
|
const dataDrive = this.form.controls.dataDrive.value
|
||||||
|
if (!osDrive || !dataDrive) return
|
||||||
|
|
||||||
const sameDevice =
|
const sameDevice = osDrive.logicalname === dataDrive.logicalname
|
||||||
this.selectedOsDrive.logicalname === this.selectedDataDrive.logicalname
|
const dataHasStartOS = !!toGuid(dataDrive)
|
||||||
const dataHasStartOS = !!toGuid(this.selectedDataDrive)
|
|
||||||
|
|
||||||
// Scenario 1: Same drive, has StartOS data, preserving → no warning
|
// Scenario 1: Same drive, has StartOS data, preserving → no warning
|
||||||
if (sameDevice && dataHasStartOS && this.preserveData) {
|
if (sameDevice && dataHasStartOS && this.preserveData) {
|
||||||
@@ -292,7 +343,7 @@ export default class DrivesPage {
|
|||||||
|
|
||||||
private showPreserveOverwriteDialog() {
|
private showPreserveOverwriteDialog() {
|
||||||
let selectionMade = false
|
let selectionMade = false
|
||||||
const drive = this.selectedDataDrive
|
const drive = this.form.controls.dataDrive.value
|
||||||
const filesystem =
|
const filesystem =
|
||||||
drive?.filesystem ||
|
drive?.filesystem ||
|
||||||
drive?.partitions.find(p => p.guid)?.filesystem ||
|
drive?.partitions.find(p => p.guid)?.filesystem ||
|
||||||
@@ -304,20 +355,20 @@ export default class DrivesPage {
|
|||||||
data: { isExt4 },
|
data: { isExt4 },
|
||||||
})
|
})
|
||||||
.subscribe({
|
.subscribe({
|
||||||
next: preserve => {
|
next: preserve => {
|
||||||
selectionMade = true
|
selectionMade = true
|
||||||
this.preserveData = preserve
|
this.preserveData = preserve
|
||||||
this.cdr.markForCheck()
|
|
||||||
},
|
|
||||||
complete: () => {
|
|
||||||
if (!selectionMade) {
|
|
||||||
// Dialog was dismissed without selection - clear the data drive
|
|
||||||
this.selectedDataDrive = null
|
|
||||||
this.preserveData = null
|
|
||||||
this.cdr.markForCheck()
|
this.cdr.markForCheck()
|
||||||
}
|
},
|
||||||
},
|
complete: () => {
|
||||||
})
|
if (!selectionMade) {
|
||||||
|
// Dialog was dismissed without selection - clear the data drive
|
||||||
|
this.form.controls.dataDrive.reset()
|
||||||
|
this.preserveData = null
|
||||||
|
this.cdr.markForCheck()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private showOsDriveWarning() {
|
private showOsDriveWarning() {
|
||||||
@@ -360,13 +411,15 @@ export default class DrivesPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async installOs(wipe: boolean) {
|
private async installOs(wipe: boolean) {
|
||||||
|
const osDrive = this.form.controls.osDrive.value!
|
||||||
|
const dataDrive = this.form.controls.dataDrive.value!
|
||||||
const loader = this.loader.open('Installing StartOS').subscribe()
|
const loader = this.loader.open('Installing StartOS').subscribe()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await this.api.installOs({
|
const result = await this.api.installOs({
|
||||||
osDrive: this.selectedOsDrive!.logicalname,
|
osDrive: osDrive.logicalname,
|
||||||
dataDrive: {
|
dataDrive: {
|
||||||
logicalname: this.selectedDataDrive!.logicalname,
|
logicalname: dataDrive.logicalname,
|
||||||
wipe,
|
wipe,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -628,8 +628,8 @@ export default {
|
|||||||
697: 'Geben Sie das Passwort ein, das zum Verschlüsseln dieses Backups verwendet wurde.',
|
697: 'Geben Sie das Passwort ein, das zum Verschlüsseln dieses Backups verwendet wurde.',
|
||||||
698: 'Mehrere Backups gefunden. Wählen Sie aus, welches wiederhergestellt werden soll.',
|
698: 'Mehrere Backups gefunden. Wählen Sie aus, welches wiederhergestellt werden soll.',
|
||||||
699: 'Backups',
|
699: 'Backups',
|
||||||
700: 'Das Laufwerk, auf dem das StartOS-Betriebssystem installiert wird.',
|
700: 'Das Laufwerk, auf dem das StartOS-Betriebssystem installiert wird. Mindestens 18 GB.',
|
||||||
701: 'Das Laufwerk, auf dem Ihre StartOS-Daten (Dienste, Einstellungen usw.) gespeichert werden. Dies kann dasselbe wie das OS-Laufwerk oder ein separates Laufwerk sein.',
|
701: 'Das Laufwerk, auf dem Ihre StartOS-Daten (Dienste, Einstellungen usw.) gespeichert werden. Dies kann dasselbe wie das OS-Laufwerk oder ein separates Laufwerk sein. Mindestens 20 GB, oder 38 GB bei Verwendung eines einzelnen Laufwerks für OS und Daten.',
|
||||||
702: 'Versuchen Sie nach der Datenübertragung von diesem Laufwerk nicht, erneut als Start9-Server davon zu booten. Dies kann zu Fehlfunktionen von Diensten, Datenbeschädigung oder Geldverlust führen.',
|
702: 'Versuchen Sie nach der Datenübertragung von diesem Laufwerk nicht, erneut als Start9-Server davon zu booten. Dies kann zu Fehlfunktionen von Diensten, Datenbeschädigung oder Geldverlust führen.',
|
||||||
703: 'Muss mindestens 12 Zeichen lang sein',
|
703: 'Muss mindestens 12 Zeichen lang sein',
|
||||||
704: 'Darf höchstens 64 Zeichen lang sein',
|
704: 'Darf höchstens 64 Zeichen lang sein',
|
||||||
@@ -724,4 +724,7 @@ export default {
|
|||||||
808: 'Hostname geändert, Neustart damit installierte Dienste die neue Adresse verwenden',
|
808: 'Hostname geändert, Neustart damit installierte Dienste die neue Adresse verwenden',
|
||||||
809: 'Sprache geändert, Neustart damit installierte Dienste die neue Sprache verwenden',
|
809: 'Sprache geändert, Neustart damit installierte Dienste die neue Sprache verwenden',
|
||||||
810: 'Kioskmodus geändert, Neustart zum Anwenden',
|
810: 'Kioskmodus geändert, Neustart zum Anwenden',
|
||||||
|
811: 'OS-Laufwerk muss mindestens 18 GB groß sein',
|
||||||
|
812: 'Datenlaufwerk muss mindestens 20 GB groß sein',
|
||||||
|
813: 'OS + Daten zusammen erfordern mindestens 38 GB',
|
||||||
} satisfies i18n
|
} satisfies i18n
|
||||||
|
|||||||
@@ -628,8 +628,8 @@ export const ENGLISH: Record<string, number> = {
|
|||||||
'Enter the password that was used to encrypt this backup.': 697,
|
'Enter the password that was used to encrypt this backup.': 697,
|
||||||
'Multiple backups found. Select which one to restore.': 698,
|
'Multiple backups found. Select which one to restore.': 698,
|
||||||
'Backups': 699,
|
'Backups': 699,
|
||||||
'The drive where the StartOS operating system will be installed.': 700,
|
'The drive where the StartOS operating system will be installed. Minimum 18 GB.': 700,
|
||||||
'The drive where your StartOS data (services, settings, etc.) will be stored. This can be the same as the OS drive or a separate drive.': 701,
|
'The drive where your StartOS data (services, settings, etc.) will be stored. This can be the same as the OS drive or a separate drive. Minimum 20 GB, or 38 GB if using a single drive for both OS and data.': 701,
|
||||||
'After transferring data from this drive, do not attempt to boot into it again as a Start9 Server. This may result in services malfunctioning, data corruption, or loss of funds.': 702,
|
'After transferring data from this drive, do not attempt to boot into it again as a Start9 Server. This may result in services malfunctioning, data corruption, or loss of funds.': 702,
|
||||||
'Must be 12 characters or greater': 703,
|
'Must be 12 characters or greater': 703,
|
||||||
'Must be 64 character or less': 704,
|
'Must be 64 character or less': 704,
|
||||||
@@ -725,4 +725,7 @@ export const ENGLISH: Record<string, number> = {
|
|||||||
'Hostname changed, restart for installed services to use the new address': 808,
|
'Hostname changed, restart for installed services to use the new address': 808,
|
||||||
'Language changed, restart for installed services to use the new language': 809,
|
'Language changed, restart for installed services to use the new language': 809,
|
||||||
'Kiosk mode changed, restart to apply': 810,
|
'Kiosk mode changed, restart to apply': 810,
|
||||||
|
'OS drive must be at least 18 GB': 811,
|
||||||
|
'Data drive must be at least 20 GB': 812,
|
||||||
|
'OS + data combined require at least 38 GB': 813,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -628,8 +628,8 @@ export default {
|
|||||||
697: 'Introduzca la contraseña que se utilizó para cifrar esta copia de seguridad.',
|
697: 'Introduzca la contraseña que se utilizó para cifrar esta copia de seguridad.',
|
||||||
698: 'Se encontraron varias copias de seguridad. Seleccione cuál restaurar.',
|
698: 'Se encontraron varias copias de seguridad. Seleccione cuál restaurar.',
|
||||||
699: 'Copias de seguridad',
|
699: 'Copias de seguridad',
|
||||||
700: 'La unidad donde se instalará el sistema operativo StartOS.',
|
700: 'La unidad donde se instalará el sistema operativo StartOS. Mínimo 18 GB.',
|
||||||
701: 'La unidad donde se almacenarán sus datos de StartOS (servicios, ajustes, etc.). Puede ser la misma que la unidad del sistema operativo o una unidad separada.',
|
701: 'La unidad donde se almacenarán sus datos de StartOS (servicios, ajustes, etc.). Puede ser la misma que la unidad del sistema operativo o una unidad separada. Mínimo 20 GB, o 38 GB si se usa una sola unidad para el sistema operativo y los datos.',
|
||||||
702: 'Después de transferir datos desde esta unidad, no intente arrancar desde ella nuevamente como un servidor Start9. Esto puede provocar fallos en los servicios, corrupción de datos o pérdida de fondos.',
|
702: 'Después de transferir datos desde esta unidad, no intente arrancar desde ella nuevamente como un servidor Start9. Esto puede provocar fallos en los servicios, corrupción de datos o pérdida de fondos.',
|
||||||
703: 'Debe tener 12 caracteres o más',
|
703: 'Debe tener 12 caracteres o más',
|
||||||
704: 'Debe tener 64 caracteres o menos',
|
704: 'Debe tener 64 caracteres o menos',
|
||||||
@@ -724,4 +724,7 @@ export default {
|
|||||||
808: 'Nombre de host cambiado, reiniciar para que los servicios instalados usen la nueva dirección',
|
808: 'Nombre de host cambiado, reiniciar para que los servicios instalados usen la nueva dirección',
|
||||||
809: 'Idioma cambiado, reiniciar para que los servicios instalados usen el nuevo idioma',
|
809: 'Idioma cambiado, reiniciar para que los servicios instalados usen el nuevo idioma',
|
||||||
810: 'Modo kiosco cambiado, reiniciar para aplicar',
|
810: 'Modo kiosco cambiado, reiniciar para aplicar',
|
||||||
|
811: 'La unidad del SO debe tener al menos 18 GB',
|
||||||
|
812: 'La unidad de datos debe tener al menos 20 GB',
|
||||||
|
813: 'SO + datos combinados requieren al menos 38 GB',
|
||||||
} satisfies i18n
|
} satisfies i18n
|
||||||
|
|||||||
@@ -628,8 +628,8 @@ export default {
|
|||||||
697: 'Saisissez le mot de passe utilisé pour chiffrer cette sauvegarde.',
|
697: 'Saisissez le mot de passe utilisé pour chiffrer cette sauvegarde.',
|
||||||
698: 'Plusieurs sauvegardes trouvées. Sélectionnez celle à restaurer.',
|
698: 'Plusieurs sauvegardes trouvées. Sélectionnez celle à restaurer.',
|
||||||
699: 'Sauvegardes',
|
699: 'Sauvegardes',
|
||||||
700: 'Le disque sur lequel le système d’exploitation StartOS sera installé.',
|
700: 'Le disque sur lequel le système d’exploitation StartOS sera installé. Minimum 18 Go.',
|
||||||
701: 'Le disque sur lequel vos données StartOS (services, paramètres, etc.) seront stockées. Il peut s’agir du même disque que le système ou d’un disque séparé.',
|
701: 'Le disque sur lequel vos données StartOS (services, paramètres, etc.) seront stockées. Il peut s’agir du même disque que le système ou d’un disque séparé. Minimum 20 Go, ou 38 Go si un seul disque est utilisé pour le système et les données.',
|
||||||
702: 'Après le transfert des données depuis ce disque, n’essayez pas de démarrer dessus à nouveau en tant que serveur Start9. Cela peut entraîner des dysfonctionnements des services, une corruption des données ou une perte de fonds.',
|
702: 'Après le transfert des données depuis ce disque, n’essayez pas de démarrer dessus à nouveau en tant que serveur Start9. Cela peut entraîner des dysfonctionnements des services, une corruption des données ou une perte de fonds.',
|
||||||
703: 'Doit comporter au moins 12 caractères',
|
703: 'Doit comporter au moins 12 caractères',
|
||||||
704: 'Doit comporter au maximum 64 caractères',
|
704: 'Doit comporter au maximum 64 caractères',
|
||||||
@@ -724,4 +724,7 @@ export default {
|
|||||||
808: "Nom d'hôte modifié, redémarrer pour que les services installés utilisent la nouvelle adresse",
|
808: "Nom d'hôte modifié, redémarrer pour que les services installés utilisent la nouvelle adresse",
|
||||||
809: 'Langue modifiée, redémarrer pour que les services installés utilisent la nouvelle langue',
|
809: 'Langue modifiée, redémarrer pour que les services installés utilisent la nouvelle langue',
|
||||||
810: 'Mode kiosque modifié, redémarrer pour appliquer',
|
810: 'Mode kiosque modifié, redémarrer pour appliquer',
|
||||||
|
811: 'Le disque système doit faire au moins 18 Go',
|
||||||
|
812: 'Le disque de données doit faire au moins 20 Go',
|
||||||
|
813: 'Système + données combinés nécessitent au moins 38 Go',
|
||||||
} satisfies i18n
|
} satisfies i18n
|
||||||
|
|||||||
@@ -628,8 +628,8 @@ export default {
|
|||||||
697: 'Wprowadź hasło użyte do zaszyfrowania tej kopii zapasowej.',
|
697: 'Wprowadź hasło użyte do zaszyfrowania tej kopii zapasowej.',
|
||||||
698: 'Znaleziono wiele kopii zapasowych. Wybierz, którą przywrócić.',
|
698: 'Znaleziono wiele kopii zapasowych. Wybierz, którą przywrócić.',
|
||||||
699: 'Kopie zapasowe',
|
699: 'Kopie zapasowe',
|
||||||
700: 'Dysk, na którym zostanie zainstalowany system operacyjny StartOS.',
|
700: 'Dysk, na którym zostanie zainstalowany system operacyjny StartOS. Minimum 18 GB.',
|
||||||
701: 'Dysk, na którym będą przechowywane dane StartOS (usługi, ustawienia itp.). Może to być ten sam dysk co systemowy lub oddzielny dysk.',
|
701: 'Dysk, na którym będą przechowywane dane StartOS (usługi, ustawienia itp.). Może to być ten sam dysk co systemowy lub oddzielny dysk. Minimum 20 GB lub 38 GB w przypadku jednego dysku na system i dane.',
|
||||||
702: 'Po przeniesieniu danych z tego dysku nie próbuj ponownie uruchamiać z niego systemu jako serwer Start9. Może to spowodować nieprawidłowe działanie usług, uszkodzenie danych lub utratę środków.',
|
702: 'Po przeniesieniu danych z tego dysku nie próbuj ponownie uruchamiać z niego systemu jako serwer Start9. Może to spowodować nieprawidłowe działanie usług, uszkodzenie danych lub utratę środków.',
|
||||||
703: 'Musi mieć co najmniej 12 znaków',
|
703: 'Musi mieć co najmniej 12 znaków',
|
||||||
704: 'Musi mieć maksymalnie 64 znaki',
|
704: 'Musi mieć maksymalnie 64 znaki',
|
||||||
@@ -724,4 +724,7 @@ export default {
|
|||||||
808: 'Nazwa hosta zmieniona, uruchom ponownie, aby zainstalowane usługi używały nowego adresu',
|
808: 'Nazwa hosta zmieniona, uruchom ponownie, aby zainstalowane usługi używały nowego adresu',
|
||||||
809: 'Język zmieniony, uruchom ponownie, aby zainstalowane usługi używały nowego języka',
|
809: 'Język zmieniony, uruchom ponownie, aby zainstalowane usługi używały nowego języka',
|
||||||
810: 'Tryb kiosku zmieniony, uruchom ponownie, aby zastosować',
|
810: 'Tryb kiosku zmieniony, uruchom ponownie, aby zastosować',
|
||||||
|
811: 'Dysk systemowy musi mieć co najmniej 18 GB',
|
||||||
|
812: 'Dysk danych musi mieć co najmniej 20 GB',
|
||||||
|
813: 'System + dane łącznie wymagają co najmniej 38 GB',
|
||||||
} satisfies i18n
|
} satisfies i18n
|
||||||
|
|||||||
Reference in New Issue
Block a user