Fix links for docs (#2908)

* fix docs paths

* docsLink directive

* fix: bugs (#2909)

---------

Co-authored-by: Alex Inkin <alexander@inkin.ru>
This commit is contained in:
Matt Hill
2025-04-24 14:14:08 -06:00
committed by GitHub
parent 2cf4864078
commit 05dd760388
29 changed files with 193 additions and 167 deletions

View File

@@ -1,6 +1,6 @@
# Contributing to StartOS
This guide is for contributing to the StartOS. If you are interested in packaging a service for StartOS, visit the [service packaging guide](https://docs.start9.com/latest/developer-docs/). If you are interested in promoting, providing technical support, creating tutorials, or helping in other ways, please visit the [Start9 website](https://start9.com/contribute).
This guide is for contributing to the StartOS. If you are interested in packaging a service for StartOS, visit the [service packaging guide](https://docs.start9.com/latest/packaging-guide/). If you are interested in promoting, providing technical support, creating tutorials, or helping in other ways, please visit the [Start9 website](https://start9.com/contribute).
## Collaboration

View File

@@ -601,10 +601,6 @@ export class StartSdk<Manifest extends T.SDKManifest, Store> {
setupPostInstall: (fn: InstallFn<Manifest, Store>) => PostInstall.of(fn),
/**
* @description Use this function to determine how this service will be hosted and served. The function executes on service install, service update, and inputSpec save.
*
* "input" will be of type `Input` for inputSpec save. It will be `null` for install and update.
*
* To learn about creating multi-hosts and interfaces, check out the {@link https://docs.start9.com/packaging-guide/learn/interfaces documentation}.
* @param inputSpec - The inputSpec spec of this service as exported from /inputSpec/spec.
* @param fn - an async function that returns an array of interface receipts. The function always has access to `effects`; it has access to `input` only after inputSpec save, otherwise `input` will be null.
* @example
@@ -612,8 +608,7 @@ export class StartSdk<Manifest extends T.SDKManifest, Store> {
*
* ```
export const setInterfaces = sdk.setupInterfaces(
inputSpecSpec,
async ({ effects, input }) => {
async ({ effects }) => {
// ** UI multi-host **
const uiMulti = sdk.MultiHost.of(effects, 'ui-multi')
const uiMultiOrigin = await uiMulti.bindPort(80, {

View File

@@ -62,7 +62,7 @@
<a
target="_blank"
rel="noreferrer"
href="https://docs.start9.com/0.3.5.x/developer-docs/"
href="https://docs.start9.com/latest/packaging-guide/"
>
<span>Package a service</span>
<tui-icon tuiAppearance="icon" icon="@tui.external-link" />
@@ -90,7 +90,7 @@
<a
target="_blank"
rel="noreferrer"
href="https://docs.start9.com/0.3.5.x/developer-docs/"
href="https://docs.start9.com/latest/packaging-guide/"
>
<span>Package a service</span>
<tui-icon tuiAppearance="icon" icon="@tui.external-link" />

View File

@@ -1,4 +1,5 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
import { DocsLinkDirective } from '@start9labs/shared'
@Component({
standalone: true,
@@ -43,9 +44,8 @@ import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
<p>
Download your server's Root CA and
<a
href="https://docs.start9.com/0.3.5.x/user-manual/connecting-lan"
target="_blank"
rel="noreferrer"
docsLink
href="/user-manual/trust-ca.html"
style="color: #6866cc; font-weight: bold; text-decoration: none"
>
follow the instructions
@@ -110,9 +110,8 @@ import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
<span style="font-weight: bold">Note:</span>
This address will only work from a Tor-enabled browser.
<a
href="https://docs.start9.com/0.3.5.x/user-manual/connecting-tor"
target="_blank"
rel="noreferrer"
docsLink
href="/user-manual/connecting-remotely/tor.html"
style="color: #6866cc; font-weight: bold; text-decoration: none"
>
Follow the instructions
@@ -135,6 +134,7 @@ import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
</html>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [DocsLinkDirective],
})
export class DocumentationComponent {
@Input({ required: true }) lanAddress!: string

View File

@@ -0,0 +1,31 @@
import {
computed,
Directive,
inject,
InjectionToken,
input,
} from '@angular/core'
const HOST = 'https://staging.docs.start9.com'
export const VERSION = new InjectionToken<string>('VERSION')
@Directive({
selector: '[docsLink]',
standalone: true,
host: {
target: '_blank',
rel: 'noreferrer',
'[href]': 'url()',
},
})
export class DocsLinkDirective {
private readonly version = inject(VERSION)
readonly href = input.required<string>()
protected readonly url = computed(() => {
const path = this.href()
const relative = path.startsWith('/') ? path : `/${path}`
return `${HOST}${relative}?os=${this.version}`
})
}

View File

@@ -13,6 +13,7 @@ export * from './components/markdown.component'
export * from './components/prompt.component'
export * from './components/server.component'
export * from './directives/docs-link.directive'
export * from './directives/drag-scroller.directive'
export * from './directives/safe-links.directive'

View File

@@ -30,7 +30,7 @@ export function getErrorMessage(e: HttpError | string, link?: string): string {
'Request Error. Your browser blocked the request. This is usually caused by a corrupt browser cache or an overly aggressive ad blocker. Please clear your browser cache and/or adjust your ad blocker and try again'
} else if (!e.message) {
message = 'Unknown Error'
link = 'https://docs.start9.com/latest/support/faq'
link = 'https://docs.start9.com/help/common-issues.html'
} else {
message = e.message
}

View File

@@ -10,6 +10,7 @@ import {
I18N_STORAGE,
i18nService,
RELATIVE_URL,
VERSION,
WorkspaceConfig,
} from '@start9labs/shared'
import {
@@ -27,6 +28,7 @@ import {
import { tuiTextfieldOptionsProvider } from '@taiga-ui/legacy'
import { PatchDB } from 'patch-db-client'
import { filter, of, pairwise } from 'rxjs'
import { ConfigService } from 'src/app/services/config.service'
import {
PATCH_CACHE,
PatchDbSource,
@@ -112,6 +114,10 @@ export const APP_PROVIDERS: Provider[] = [
return (language: string) => api.setDbValue(['language'], language)
},
},
{
provide: VERSION,
useFactory: () => inject(ConfigService).version,
},
]
export function appInitializer(): () => void {

View File

@@ -2,7 +2,7 @@ import { AsyncPipe } from '@angular/common'
import { ChangeDetectionStrategy, Component, inject } from '@angular/core'
import { RouterLink } from '@angular/router'
import { i18nPipe } from '@start9labs/shared'
import { TuiAlert } from '@taiga-ui/core'
import { TuiAlert, TuiLink } from '@taiga-ui/core'
import { PatchDB } from 'patch-db-client'
import { endWith, map, merge, Observable, pairwise, Subject } from 'rxjs'
import { DataModel } from 'src/app/services/patch-db/data-model'
@@ -17,13 +17,17 @@ import { DataModel } from 'src/app/services/patch-db/data-model'
(tuiAlertChange)="onDismiss()"
>
{{ 'New notifications' | i18n }}
<a routerLink="/notifications" [queryParams]="{ toast: true }">
<a
tuiLink
routerLink="/portal/notifications"
[queryParams]="{ toast: true }"
>
{{ 'View' | i18n }}
</a>
</ng-template>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [TuiAlert, RouterLink, AsyncPipe, i18nPipe],
imports: [TuiAlert, RouterLink, AsyncPipe, i18nPipe, TuiLink],
})
export class NotificationsToastComponent {
private readonly dismiss$ = new Subject<boolean>()

View File

@@ -7,16 +7,27 @@
<tui-icon icon="@tui.lock" [style.font-size.rem]="4" />
<h1>{{ 'Trust your Root CA' | i18n }}</h1>
<p>
{{ 'Download and trust your Root Certificate Authority to establish a secure (HTTPS) connection. You will need to repeat this on every device you use to connect to your server.' | i18n }}
{{
'Download and trust your Root Certificate Authority to establish a secure (HTTPS) connection. You will need to repeat this on every device you use to connect to your server.'
| i18n
}}
</p>
<ol>
<li>
<b>{{ 'Bookmark this page' | i18n }}</b>
- {{ 'Save this page so you can access it later. You can also find this address in the file downloaded at the end of initial setup.' | i18n }}
-
{{
'Save this page so you can access it later. You can also find this address in the file downloaded at the end of initial setup.'
| i18n
}}
</li>
<li>
<b>{{ 'Download your Root CA' | i18n }}</b>
- {{ 'Your server uses its Root CA to generate SSL/TLS certificates for itself and installed services. These certificates are then used to encrypt network traffic with your client devices.' | i18n }}
-
{{
'Your server uses its Root CA to generate SSL/TLS certificates for itself and installed services. These certificates are then used to encrypt network traffic with your client devices.'
| i18n
}}
<br />
<a
tuiButton
@@ -29,14 +40,17 @@
</li>
<li>
<b>{{ 'Trust your Root CA' | i18n }}</b>
- {{ 'Follow instructions for your OS. By trusting your Root CA, your device can verify the authenticity of encrypted communications with your server.' | i18n }}
-
{{
'Follow instructions for your OS. By trusting your Root CA, your device can verify the authenticity of encrypted communications with your server.'
| i18n
}}
<br />
<a
tuiButton
docsLink
size="s"
href="https://docs.start9.com/0.3.5.x/user-manual/trust-ca"
target="_blank"
rel="noreferrer"
href="/user-manual/trust-ca.html"
iconEnd="@tui.external-link"
>
{{ 'View instructions' | i18n }}
@@ -44,7 +58,11 @@
</li>
<li>
<b>{{ 'Test' | i18n }}</b>
- {{ 'Refresh the page. If refreshing the page does not work, you may need to quit and re-open your browser, then revisit this page.' | i18n }}
-
{{
'Refresh the page. If refreshing the page does not work, you may need to quit and re-open your browser, then revisit this page.'
| i18n
}}
<br />
<button
tuiButton
@@ -68,7 +86,9 @@
>
{{ 'Skip' | i18n }}
</button>
<div><small>({{ 'not recommended' | i18n }})</small></div>
<div>
<small>({{ 'not recommended' | i18n }})</small>
</div>
</div>
<ng-template #trusted>
@@ -76,7 +96,10 @@
<tui-icon icon="@tui.shield" class="g-positive" [style.font-size.rem]="4" />
<h1>{{ 'Root CA Trusted!' | i18n }}</h1>
<p>
{{ 'You have successfully trusted your Root CA and may now log in securely.' | i18n }}
{{
'You have successfully trusted your Root CA and may now log in securely.'
| i18n
}}
</p>
<button tuiButton iconEnd="@tui.external-link" (click)="launchHttps()">
{{ 'Go to login' | i18n }}

View File

@@ -1,6 +1,6 @@
import { CommonModule, DOCUMENT } from '@angular/common'
import { Component, inject } from '@angular/core'
import { i18nPipe, RELATIVE_URL } from '@start9labs/shared'
import { DocsLinkDirective, i18nPipe, RELATIVE_URL } from '@start9labs/shared'
import { TuiButton, TuiIcon, TuiSurface } from '@taiga-ui/core'
import { TuiCardLarge } from '@taiga-ui/layout'
import { ApiService } from 'src/app/services/api/embassy-api.service'
@@ -18,6 +18,7 @@ import { ConfigService } from 'src/app/services/config.service'
TuiCardLarge,
TuiSurface,
i18nPipe,
DocsLinkDirective,
],
})
export class CAWizardComponent {

View File

@@ -1,16 +1,17 @@
import { TuiCell } from '@taiga-ui/layout'
import { TuiTitle, TuiButton } from '@taiga-ui/core'
import { CommonModule } from '@angular/common'
import { ChangeDetectionStrategy, Component, inject } from '@angular/core'
import { toSignal } from '@angular/core/rxjs-interop'
import { CopyService, i18nPipe } from '@start9labs/shared'
import { TuiButton, TuiTitle } from '@taiga-ui/core'
import { TuiFade } from '@taiga-ui/kit'
import { TuiCell } from '@taiga-ui/layout'
import { PolymorpheusComponent } from '@taiga-ui/polymorpheus'
import { PatchDB } from 'patch-db-client'
import { DataModel } from 'src/app/services/patch-db/data-model'
import { ConfigService } from 'src/app/services/config.service'
import { DataModel } from 'src/app/services/patch-db/data-model'
@Component({
template: `
<ng-container *ngIf="server$ | async as server">
@if (server(); as server) {
<div tuiCell>
<div tuiTitle>
<strong>{{ 'Version' | i18n }}</strong>
@@ -20,7 +21,7 @@ import { ConfigService } from 'src/app/services/config.service'
<div tuiCell>
<div tuiTitle>
<strong>Git Hash</strong>
<div tuiSubtitle>{{ gitHash }}</div>
<div tuiSubtitle tuiFade>{{ gitHash }}</div>
</div>
<button
tuiIconButton
@@ -34,7 +35,7 @@ import { ConfigService } from 'src/app/services/config.service'
<div tuiCell>
<div tuiTitle>
<strong>CA fingerprint</strong>
<div tuiSubtitle>{{ server.caFingerprint }}</div>
<div tuiSubtitle tuiFade>{{ server.caFingerprint }}</div>
</div>
<button
tuiIconButton
@@ -45,17 +46,19 @@ import { ConfigService } from 'src/app/services/config.service'
{{ 'Copy' | i18n }}
</button>
</div>
</ng-container>
}
`,
styles: ['[tuiCell] { padding-inline: 0 }'],
styles: '[tuiCell] { padding-inline: 0; white-space: nowrap }',
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [CommonModule, TuiTitle, TuiButton, TuiCell, i18nPipe],
imports: [TuiTitle, TuiButton, TuiCell, i18nPipe, TuiFade],
})
export class AboutComponent {
readonly server$ = inject<PatchDB<DataModel>>(PatchDB).watch$('serverInfo')
readonly copyService = inject(CopyService)
readonly gitHash = inject(ConfigService).gitHash
readonly server = toSignal(
inject<PatchDB<DataModel>>(PatchDB).watch$('serverInfo'),
)
}
export const ABOUT = new PolymorpheusComponent(AboutComponent)

View File

@@ -1,10 +1,12 @@
import { ChangeDetectionStrategy, Component, inject } from '@angular/core'
import { RouterLink, RouterLinkActive } from '@angular/router'
import { RouterLink } from '@angular/router'
import {
DialogService,
DocsLinkDirective,
ErrorService,
i18nPipe,
LoadingService,
SafeLinksDirective,
} from '@start9labs/shared'
import {
TuiButton,
@@ -17,7 +19,6 @@ import { filter } from 'rxjs'
import { ApiService } from 'src/app/services/api/embassy-api.service'
import { AuthService } from 'src/app/services/auth.service'
import { STATUS } from 'src/app/services/status.service'
import { RESOURCES } from 'src/app/utils/resources'
import { ABOUT } from './about.component'
@Component({
@@ -48,18 +49,24 @@ import { ABOUT } from './about.component'
{{ 'About this server' | i18n }}
</button>
</tui-opt-group>
<tui-opt-group label="">
@for (link of links; track $index) {
<a
tuiOption
target="_blank"
rel="noreferrer"
[iconStart]="link.icon"
[href]="link.href"
>
{{ link.name | i18n }}
</a>
}
<tui-opt-group label="" safeLinks>
<a tuiOption docsLink iconStart="@tui.book-open" href="/user-manual">
{{ 'User manual' | i18n }}
</a>
<a
tuiOption
iconStart="@tui.headphones"
href="https://start9.com/contact"
>
{{ 'Contact support' | i18n }}
</a>
<a
tuiOption
iconStart="@tui.dollar-sign"
href="https://donate.start9.com"
>
{{ 'Donate to Start9' | i18n }}
</a>
</tui-opt-group>
<tui-opt-group label="">
<a
@@ -128,8 +135,9 @@ import { ABOUT } from './about.component'
TuiIcon,
RouterLink,
i18nPipe,
RouterLinkActive,
TuiHint,
DocsLinkDirective,
SafeLinksDirective,
],
})
export class HeaderMenuComponent {
@@ -141,7 +149,6 @@ export class HeaderMenuComponent {
open = false
readonly links = RESOURCES
readonly status = inject(STATUS)
about() {

View File

@@ -59,7 +59,7 @@ type ClearnetForm = {
}}
<a
tuiLink
href="https://docs.start9.com/latest/user-manual/interface-addresses#clearnet"
href="/user-manual/connecting-remotely/clearnet.html"
target="_blank"
rel="noreferrer"
>

View File

@@ -5,7 +5,7 @@ import { TableComponent } from 'src/app/routes/portal/components/table.component
import { InterfaceActionsComponent } from './actions.component'
import { AddressDetails } from './interface.utils'
import { MaskPipe } from './mask.pipe'
import { i18nPipe } from '@start9labs/shared'
import { DocsLinkDirective, i18nPipe } from '@start9labs/shared'
@Component({
standalone: true,
@@ -19,12 +19,7 @@ import { i18nPipe } from '@start9labs/shared'
'Local addresses can only be accessed by devices connected to the same LAN as your server, either directly or using a VPN.'
| i18n
}}
<a
tuiLink
href="https://docs.start9.com/latest/user-manual/interface-addresses#local"
target="_blank"
rel="noreferrer"
>
<a tuiLink docsLink href="/user-manual/connecting-locally.html">
{{ 'Learn More' | i18n }}
</a>
</ng-template>
@@ -48,6 +43,7 @@ import { i18nPipe } from '@start9labs/shared'
InterfaceActionsComponent,
MaskPipe,
i18nPipe,
DocsLinkDirective,
],
changeDetection: ChangeDetectionStrategy.OnPush,
})

View File

@@ -6,6 +6,7 @@ import {
} from '@angular/core'
import {
DialogService,
DocsLinkDirective,
ErrorService,
i18nPipe,
LoadingService,
@@ -50,12 +51,7 @@ type OnionForm = {
'Add an onion address to anonymously expose this interface on the darknet. Onion addresses can only be reached over the Tor network.'
| i18n
}}
<a
tuiLink
href="https://docs.start9.com/latest/user-manual/interface-addresses#tor"
target="_blank"
rel="noreferrer"
>
<a tuiLink docsLink href="/user-manual/connecting-remotely/tor.html">
{{ 'Learn More' | i18n }}
</a>
</ng-template>
@@ -131,6 +127,7 @@ type OnionForm = {
TuiFade,
TuiFluidTypography,
i18nPipe,
DocsLinkDirective,
],
changeDetection: ChangeDetectionStrategy.OnPush,
})

View File

@@ -18,6 +18,7 @@ import { GetBackupIconPipe } from '../pipes/get-backup-icon.pipe'
import { ToHumanCronPipe } from '../pipes/to-human-cron.pipe'
import { BackupJobBuilder } from '../utils/job-builder'
import { EDIT } from './edit.component'
import { DocsLinkDirective } from 'projects/shared/src/public-api'
@Component({
template: `
@@ -25,14 +26,7 @@ import { EDIT } from './edit.component'
Scheduling automatic backups is an excellent way to ensure your StartOS
data is safely backed up. StartOS will issue a notification whenever one
of your scheduled backups succeeds or fails.
<a
tuiLink
href="https://docs.start9.com/latest/user-manual/backups/backup-jobs"
target="_blank"
rel="noreferrer"
>
View instructions
</a>
<a tuiLink docsLink href="/@TODO">View instructions</a>
</tui-notification>
<h3 class="g-title">
Saved Jobs
@@ -147,6 +141,7 @@ import { EDIT } from './edit.component'
GetBackupIconPipe,
TuiSkeleton,
TuiLink,
DocsLinkDirective,
],
})
export class BackupsJobsModal implements OnInit {

View File

@@ -23,6 +23,7 @@ import {
googleDriveSpec,
remoteBackupTargetSpec,
} from '../types/target'
import { DocsLinkDirective } from 'projects/shared/src/public-api'
@Component({
template: `
@@ -31,14 +32,7 @@ import {
backups. They can be physical drives plugged into your server, shared
folders on your Local Area Network (LAN), or third party clouds such as
Dropbox or Google Drive.
<a
tuiLink
href="https://docs.start9.com/latest/user-manual/backups/backup-targets"
target="_blank"
rel="noreferrer"
>
View instructions
</a>
<a tuiLink docsLink href="/@TODO">View instructions</a>
</tui-notification>
<h3 class="g-title">
Unknown Physical Drives
@@ -77,6 +71,7 @@ import {
BackupsPhysicalComponent,
BackupsTargetsComponent,
TuiLink,
DocsLinkDirective,
],
})
export class BackupsTargetsModal implements OnInit {

View File

@@ -1,7 +1,7 @@
import { CommonModule } from '@angular/common'
import { ChangeDetectionStrategy, Component, inject } from '@angular/core'
import { toSignal } from '@angular/core/rxjs-interop'
import { i18nPipe } from '@start9labs/shared'
import { DocsLinkDirective, i18nPipe } from '@start9labs/shared'
import {
TuiHint,
TuiIcon,
@@ -47,11 +47,10 @@ import { TimeService } from 'src/app/services/time.service'
To resolve it, refer to
<a
tuiLink
docsLink
iconEnd="@tui.external-link"
appearance=""
href="https://docs.start9.com/0.3.5.x/support/common-issues#clock-sync-failure"
target="_blank"
rel="noreferrer"
href="/help/common-issues.html#clock-sync-failure"
[pseudo]="true"
[textContent]="'the docs' | i18n"
></a>
@@ -110,6 +109,7 @@ import { TimeService } from 'src/app/services/time.service'
TuiIcon,
TuiHint,
i18nPipe,
DocsLinkDirective,
],
})
export class TimeComponent {

View File

@@ -1,7 +1,12 @@
import { ChangeDetectionStrategy, Component, inject } from '@angular/core'
import { toSignal } from '@angular/core/rxjs-interop'
import { RouterLink } from '@angular/router'
import { ErrorService, i18nPipe, LoadingService } from '@start9labs/shared'
import {
DocsLinkDirective,
ErrorService,
i18nPipe,
LoadingService,
} from '@start9labs/shared'
import { ISB, utils } from '@start9labs/start-sdk'
import { TuiButton, TuiLink, TuiLoader, TuiTitle } from '@taiga-ui/core'
import { TuiCell, TuiHeader } from '@taiga-ui/layout'
@@ -33,9 +38,8 @@ import { configBuilderToSpec } from 'src/app/utils/configBuilderToSpec'
}}
<a
tuiLink
href="https://docs.start9.com/latest/user-manual/acme"
target="_blank"
rel="noreferrer"
docsLink
href="/user-manual/connecting-remotely/clearnet.html#adding-acme"
appearance="action-grayscale"
iconEnd="@tui.external-link"
[pseudo]="true"
@@ -108,6 +112,7 @@ import { configBuilderToSpec } from 'src/app/utils/configBuilderToSpec'
RouterLink,
TitleDirective,
i18nPipe,
DocsLinkDirective,
],
})
export default class SystemAcmeComponent {

View File

@@ -9,6 +9,7 @@ import { toSignal } from '@angular/core/rxjs-interop'
import { ActivatedRoute, RouterLink } from '@angular/router'
import {
DialogService,
DocsLinkDirective,
i18nPipe,
UnitConversionPipesModule,
} from '@start9labs/shared'
@@ -64,9 +65,8 @@ import { BACKUP_RESTORE } from './restore.component'
}}
<a
tuiLink
href="https://docs.start9.com/0.3.5.x/user-manual/backups/backup-create"
target="_blank"
rel="noreferrer"
docsLink
href="/user-manual/backup-create.html"
appearance="action-grayscale"
iconEnd="@tui.external-link"
[pseudo]="true"
@@ -79,9 +79,8 @@ import { BACKUP_RESTORE } from './restore.component'
}}
<a
tuiLink
href="https://docs.start9.com/0.3.5.x/user-manual/backups/backup-restore"
target="_blank"
rel="noreferrer"
docsLink
href="/user-manual/backup-restore.html"
appearance="action-grayscale"
iconEnd="@tui.external-link"
[pseudo]="true"
@@ -120,9 +119,8 @@ import { BACKUP_RESTORE } from './restore.component'
}}
<a
tuiLink
href="https://docs.start9.com/0.3.5.x/user-manual/backups/backup-create#network-folder"
target="_blank"
rel="noreferrer"
docsLink
href="/user-manual/backup-create.html#network-folder"
appearance="action-grayscale"
iconEnd="@tui.external-link"
[pseudo]="true"
@@ -157,6 +155,7 @@ import { BACKUP_RESTORE } from './restore.component'
BackupPhysicalComponent,
BackupProgressComponent,
i18nPipe,
DocsLinkDirective,
],
})
export default class SystemBackupComponent implements OnInit {

View File

@@ -1,23 +1,17 @@
import { ChangeDetectionStrategy, Component } from '@angular/core'
import { TuiLink, TuiNotification } from '@taiga-ui/core'
import { DocsLinkDirective } from 'projects/shared/src/public-api'
@Component({
selector: 'domains-info',
template: `
<tui-notification>
Adding domains permits accessing your server and services over clearnet.
<a
tuiLink
href="https://docs.start9.com/latest/user-manual/domains"
target="_blank"
rel="noreferrer"
>
View instructions
</a>
<a tuiLink docsLink href="/@TODO">View instructions</a>
</tui-notification>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [TuiNotification, TuiLink],
imports: [TuiNotification, TuiLink, DocsLinkDirective],
})
export class DomainsInfoComponent {}

View File

@@ -4,6 +4,7 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { RouterLink } from '@angular/router'
import {
DialogService,
DocsLinkDirective,
ErrorService,
i18nKey,
i18nPipe,
@@ -40,9 +41,8 @@ import { configBuilderToSpec } from 'src/app/utils/configBuilderToSpec'
}}
<a
tuiLink
href="https://docs.start9.com/latest/user-manual/smtp"
target="_blank"
rel="noreferrer"
docsLink
href="/user-manual/smtp"
appearance="action-grayscale"
iconEnd="@tui.external-link"
[pseudo]="true"
@@ -140,6 +140,7 @@ import { configBuilderToSpec } from 'src/app/utils/configBuilderToSpec'
RouterLink,
TitleDirective,
i18nPipe,
DocsLinkDirective,
],
})
export default class SystemEmailComponent {

View File

@@ -229,6 +229,7 @@ export default class SystemGeneralComponent {
private readonly document = inject(DOCUMENT)
private readonly dialog = inject(DialogService)
private readonly i18n = inject(i18nPipe)
private readonly injector = inject(INJECTOR)
wipe = false
count = 0
@@ -261,7 +262,7 @@ export default class SystemGeneralComponent {
}
onTitle() {
this.dialog
const sub = this.dialog
.openPrompt<string>({
label: 'Browser Tab Title',
data: {
@@ -279,8 +280,11 @@ export default class SystemGeneralComponent {
try {
await this.api.setDbValue(['name'], name || null)
} catch (e: any) {
this.errorService.handleError(e)
} finally {
loader.unsubscribe()
sub.unsubscribe()
}
})
}
@@ -293,7 +297,7 @@ export default class SystemGeneralComponent {
data: {
content: new PolymorpheusComponent(
SystemWipeComponent,
inject(INJECTOR),
this.injector,
),
yes: 'Reset',
no: 'Cancel',

View File

@@ -1,5 +1,6 @@
import { ChangeDetectionStrategy, Component } from '@angular/core'
import { TuiLink, TuiNotification } from '@taiga-ui/core'
import { DocsLinkDirective } from 'projects/shared/src/public-api'
@Component({
selector: 'proxies-info',
@@ -24,18 +25,11 @@ import { TuiLink, TuiNotification } from '@taiga-ui/core'
VPN access to your server/services
</li>
</ol>
<a
tuiLink
href="https://docs.start9.com/latest/user-manual/vpns/"
target="_blank"
rel="noreferrer"
>
View instructions
</a>
<a tuiLink docsLink href="/@TODO">View instructions</a>
</tui-notification>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [TuiNotification, TuiLink],
imports: [TuiNotification, TuiLink, DocsLinkDirective],
})
export class ProxiesInfoComponent {}

View File

@@ -1,5 +1,6 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
import { TuiLink, TuiNotification } from '@taiga-ui/core'
import { DocsLinkDirective } from 'projects/shared/src/public-api'
@Component({
selector: 'router-info',
@@ -14,14 +15,7 @@ import { TuiLink, TuiNotification } from '@taiga-ui/core'
</p>
If you are running multiple servers, you may want to override specific
ports to suite your needs.
<a
tuiLink
href="https://docs.start9.com/latest/user-manual/port-forwards/upnp#override"
target="_blank"
rel="noreferrer"
>
View instructions
</a>
<a tuiLink docsLink href="/@TODO">View instructions</a>
} @else {
<strong>UPnP Disabled</strong>
<p>
@@ -31,21 +25,14 @@ import { TuiLink, TuiNotification } from '@taiga-ui/core'
</p>
Alternatively, you can enable UPnP in your router for automatic
configuration.
<a
tuiLink
href="https://docs.start9.com/latest/user-manual/port-forwards/manual"
target="_blank"
rel="noreferrer"
>
View instructions
</a>
<a tuiLink docsLink href="/@TODO">View instructions</a>
}
</tui-notification>
`,
styles: ['strong { font-size: 1rem }'],
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [TuiNotification, TuiLink],
imports: [TuiNotification, TuiLink, DocsLinkDirective],
})
export class RouterInfoComponent {
@Input()

View File

@@ -9,6 +9,7 @@ import { catchError, defer, of } from 'rxjs'
import { ApiService } from 'src/app/services/api/embassy-api.service'
import { TitleDirective } from 'src/app/services/title.service'
import { SSHTableComponent } from './table.component'
import { DocsLinkDirective } from 'projects/shared/src/public-api'
@Component({
template: `
@@ -23,9 +24,8 @@ import { SSHTableComponent } from './table.component'
Manage your SSH keys to access your server from the command line
<a
tuiLink
href="https://docs.start9.com/latest/user-manual/ssh"
target="_blank"
rel="noreferrer"
docsLink
href="/@TODO"
appearance="action-grayscale"
iconEnd="@tui.external-link"
[pseudo]="true"
@@ -62,6 +62,7 @@ import { SSHTableComponent } from './table.component'
TuiHeader,
TuiTitle,
TuiLink,
DocsLinkDirective,
],
})
export default class SystemSSHComponent {

View File

@@ -1,19 +0,0 @@
import { i18nKey } from '@start9labs/shared'
export const RESOURCES: { name: i18nKey; icon: string; href: string }[] = [
{
name: 'User manual',
icon: '@tui.book-open',
href: 'https://docs.start9.com/0.3.5.x/user-manual',
},
{
name: 'Contact support',
icon: '@tui.headphones',
href: 'https://start9.com/contact',
},
{
name: 'Donate to Start9',
icon: '@tui.dollar-sign',
href: 'https://donate.start9.com',
},
]

View File

@@ -1,5 +1,9 @@
@import '@taiga-ui/core/styles/taiga-ui-local';
:root {
color-scheme: light dark;
}
* {
box-sizing: border-box;
}
@@ -21,7 +25,9 @@ hr {
:root {
--bumper: 0.375rem;
--tui-font-text: 'Proxima Nova', 'Manrope', -apple-system, 'BlinkMacSystemFont', system-ui, 'Roboto', 'Segoe UI', 'Helvetica Neue', sans-serif;
--tui-font-text: 'Proxima Nova', 'Manrope', -apple-system,
'BlinkMacSystemFont', system-ui, 'Roboto', 'Segoe UI', 'Helvetica Neue',
sans-serif;
}
.g-page {