Files
start-os/web/projects/setup-wizard/src/app/pages/success.page.ts
Aiden McClelland 377b7b12ce update/alpha.9 (#2988)
* import marketplac preview for sideload

* fix: improve state service (#2977)

* fix: fix sideload DI

* fix: update Angular

* fix: cleanup

* fix: fix version selection

* Bump node version to fix build for Angular

* misc fixes
- update node to v22
- fix chroot-and-upgrade access to prune-images
- don't self-migrate legacy packages
- #2985
- move dataVersion to volume folder
- remove "instructions.md" from s9pk
- add "docsUrl" to manifest

* version bump

* include flavor when clicking view listing from updates tab

* closes #2980

* fix: fix select button

* bring back ssh keys

* fix: drop 'portal' from all routes

* fix: implement longtap action to select table rows

* fix description for ssh page

* replace instructions with docsLink and refactor marketplace preview

* delete unused translations

* fix patchdb diffing algorithm

* continue refactor of marketplace lib show components

* Booting StartOS instead of Setting up your server on init

* misc fixes
- closes #2990
- closes #2987

* fix build

* docsUrl and clickable service headers

* don't cleanup after update until new service install succeeds

* update types

* misc fixes

* beta.35

* sdkversion, githash for sideload, correct logs for init, startos pubkey display

* bring back reboot button on install

* misc fixes

* beta.36

* better handling of setup and init for websocket errors

* reopen init and setup logs even on graceful closure

* better logging, misc fixes

* fix build

* dont let package stats hang

* dont show docsurl in marketplace if no docsurl

* re-add needs-config

* show error if init fails, shorten hover state on header icons

* fix operator precedemce

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>
Co-authored-by: Alex Inkin <alexander@inkin.ru>
Co-authored-by: Mariusz Kogen <k0gen@pm.me>
2025-07-18 18:31:12 +00:00

169 lines
4.7 KiB
TypeScript

import {
AfterViewInit,
Component,
ElementRef,
inject,
ViewChild,
DOCUMENT,
} from '@angular/core'
import { DownloadHTMLService, ErrorService } from '@start9labs/shared'
import { TuiButton, TuiIcon, TuiSurface } from '@taiga-ui/core'
import { TuiCardLarge } from '@taiga-ui/layout'
import { DocumentationComponent } from 'src/app/components/documentation.component'
import { MatrixComponent } from 'src/app/components/matrix.component'
import { ApiService } from 'src/app/services/api.service'
import { StateService } from 'src/app/services/state.service'
@Component({
template: `
<canvas matrix></canvas>
<section tuiCardLarge>
<h1 class="heading">
<tui-icon icon="@tui.circle-check-big" class="g-positive" />
Setup Complete!
</h1>
@if (stateService.kiosk) {
<button tuiButton (click)="exitKiosk()">Continue to Login</button>
} @else if (lanAddress) {
@if (stateService.setupType === 'restore') {
<h3>You can now safely unplug your backup drive</h3>
} @else if (stateService.setupType === 'transfer') {
<h3>You can now safely unplug your old StartOS data drive</h3>
}
<button tuiCardLarge tuiSurface="floating" (click)="download()">
<strong class="caps">Download address info</strong>
<span>
start.local was for setup purposes only. It will no longer work.
</span>
<strong class="caps">
Download
<tui-icon icon="@tui.download" />
</strong>
</button>
<a
tuiCardLarge
tuiSurface="floating"
target="_blank"
[attr.href]="disableLogin ? null : lanAddress"
>
<strong class="caps">Trust your Root CA</strong>
<span>
In the new tab, follow instructions to trust your server's Root CA
and log in.
</span>
<strong class="caps">
Open
<tui-icon icon="@tui.external-link" />
</strong>
</a>
<app-documentation hidden [lanAddress]="lanAddress" />
}
</section>
`,
styles: `
.heading {
display: flex;
gap: 1rem;
align-items: center;
margin: 0;
font: var(--tui-font-heading-4);
}
.caps {
display: flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
text-transform: uppercase;
}
[tuiCardLarge] {
color: var(--tui-text-primary);
text-decoration: none;
text-align: center;
&[data-appearance='floating'] {
background: var(--tui-background-neutral-1);
&:hover {
background: var(--tui-background-neutral-1-hover) !important;
}
}
}
a[tuiCardLarge]:not([href]) {
opacity: var(--tui-disabled-opacity);
pointer-events: none;
}
`,
imports: [
TuiCardLarge,
TuiIcon,
TuiButton,
TuiSurface,
MatrixComponent,
DocumentationComponent,
],
})
export default class SuccessPage implements AfterViewInit {
@ViewChild(DocumentationComponent, { read: ElementRef })
private readonly documentation?: ElementRef<HTMLElement>
private readonly document = inject(DOCUMENT)
private readonly errorService = inject(ErrorService)
private readonly api = inject(ApiService)
private readonly downloadHtml = inject(DownloadHTMLService)
readonly stateService = inject(StateService)
torAddresses?: string[]
lanAddress?: string
cert?: string
disableLogin = this.stateService.setupType === 'fresh'
ngAfterViewInit() {
setTimeout(() => this.complete(), 1000)
}
download() {
const torAddress = this.document.getElementById('tor-addr')
const lanAddress = this.document.getElementById('lan-addr')
const html = this.documentation?.nativeElement.innerHTML || ''
if (torAddress) torAddress.innerHTML = this.torAddresses?.join('\n') || ''
if (lanAddress) lanAddress.innerHTML = this.lanAddress || ''
this.document
.getElementById('cert')
?.setAttribute(
'href',
`data:application/x-x509-ca-cert;base64,${encodeURIComponent(this.cert!)}`,
)
this.downloadHtml.download('StartOS-info.html', html).then(_ => {
this.disableLogin = false
})
}
exitKiosk() {
this.api.exit()
}
private async complete() {
try {
const ret = await this.api.complete()
if (!this.stateService.kiosk) {
this.torAddresses = ret.torAddresses.map(a =>
a.replace(/^https:/, 'http:'),
)
this.lanAddress = ret.lanAddress.replace(/^https:/, 'http:')
this.cert = ret.rootCa
await this.api.exit()
}
} catch (e: any) {
this.errorService.handleError(e)
}
}
}