mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 20:14:49 +00:00
fix ssh, undeprecate wifi (#3121)
This commit is contained in:
@@ -28,7 +28,7 @@ import { configBuilderToSpec } from 'src/app/utils/configBuilderToSpec'
|
||||
<a routerLink=".." tuiIconButton iconStart="@tui.arrow-left">
|
||||
{{ 'Back' | i18n }}
|
||||
</a>
|
||||
{{ 'Email' | i18n }}
|
||||
{{ 'SMTP' | i18n }}
|
||||
</ng-container>
|
||||
@if (form$ | async; as form) {
|
||||
<form [formGroup]="form">
|
||||
|
||||
@@ -160,7 +160,11 @@ export default class SystemSSHComponent {
|
||||
const loader = this.loader.open('Deleting').subscribe()
|
||||
|
||||
try {
|
||||
await this.api.deleteSshKey({ fingerprint: '' })
|
||||
await Promise.all(
|
||||
fingerprints.map(fingerprint =>
|
||||
this.api.deleteSshKey({ fingerprint }),
|
||||
),
|
||||
)
|
||||
this.local$.next(
|
||||
all.filter(s => !fingerprints.includes(s.fingerprint)),
|
||||
)
|
||||
|
||||
@@ -5,8 +5,23 @@ import {
|
||||
inject,
|
||||
Input,
|
||||
} from '@angular/core'
|
||||
import { ErrorService, i18nPipe, LoadingService } from '@start9labs/shared'
|
||||
import { TuiButton, TuiIcon, TuiTitle } from '@taiga-ui/core'
|
||||
import { NgTemplateOutlet } from '@angular/common'
|
||||
import {
|
||||
DialogService,
|
||||
ErrorService,
|
||||
i18nPipe,
|
||||
LoadingService,
|
||||
} from '@start9labs/shared'
|
||||
import { filter } from 'rxjs'
|
||||
import { IST } from '@start9labs/start-sdk'
|
||||
import {
|
||||
TuiButton,
|
||||
TuiDataList,
|
||||
TuiDropdown,
|
||||
TuiIcon,
|
||||
TuiTextfield,
|
||||
TuiTitle,
|
||||
} from '@taiga-ui/core'
|
||||
import { TuiBadge, TuiFade } from '@taiga-ui/kit'
|
||||
import { TuiCell } from '@taiga-ui/layout'
|
||||
import {
|
||||
@@ -22,50 +37,78 @@ import { wifiSpec } from './wifi.const'
|
||||
@Component({
|
||||
selector: '[wifi]',
|
||||
template: `
|
||||
@for (network of wifi; track $index) {
|
||||
@if (network.ssid) {
|
||||
<ng-template #row let-network>
|
||||
@if (getSignal(network.strength); as signal) {
|
||||
<tui-icon
|
||||
background="@tui.wifi"
|
||||
[icon]="signal.icon"
|
||||
[style.background]="'var(--tui-background-neutral-2)'"
|
||||
[style.color]="signal.color"
|
||||
/>
|
||||
} @else {
|
||||
<tui-icon icon="@tui.wifi-off" />
|
||||
}
|
||||
<tui-icon
|
||||
[icon]="network.security.length ? '@tui.lock' : '@tui.lock-open'"
|
||||
/>
|
||||
<div tuiTitle>
|
||||
<strong tuiFade>
|
||||
{{ network.ssid }}
|
||||
</strong>
|
||||
</div>
|
||||
@if (network.connected) {
|
||||
<tui-badge appearance="positive">
|
||||
{{ 'Connected' | i18n }}
|
||||
</tui-badge>
|
||||
}
|
||||
@if (network.connected === false) {
|
||||
<button
|
||||
tuiCell
|
||||
[disabled]="network.connected"
|
||||
(click)="prompt(network)"
|
||||
tuiIconButton
|
||||
tuiDropdown
|
||||
size="s"
|
||||
appearance="flat-grayscale"
|
||||
iconStart="@tui.ellipsis-vertical"
|
||||
[(tuiDropdownOpen)]="open"
|
||||
>
|
||||
<div tuiTitle>
|
||||
<strong tuiFade>
|
||||
{{ network.ssid }}
|
||||
@if (network.connected) {
|
||||
<tui-badge appearance="positive">
|
||||
{{ 'Connected' | i18n }}
|
||||
</tui-badge>
|
||||
}
|
||||
</strong>
|
||||
</div>
|
||||
@if (network.connected !== undefined) {
|
||||
{{ 'More' | i18n }}
|
||||
<tui-data-list *tuiTextfieldDropdown>
|
||||
<button
|
||||
tuiIconButton
|
||||
size="s"
|
||||
appearance="icon"
|
||||
iconStart="@tui.trash-2"
|
||||
(click.stop)="forget(network)"
|
||||
tuiOption
|
||||
new
|
||||
iconStart="@tui.wifi"
|
||||
(click)="prompt(network)"
|
||||
>
|
||||
{{ 'Connect' | i18n }}
|
||||
</button>
|
||||
<button
|
||||
tuiOption
|
||||
new
|
||||
iconStart="@tui.trash"
|
||||
class="g-negative"
|
||||
(click)="forget(network)"
|
||||
>
|
||||
{{ 'Forget' | i18n }}
|
||||
</button>
|
||||
} @else {
|
||||
<tui-icon
|
||||
[icon]="network.security.length ? '@tui.lock' : '@tui.lock-open'"
|
||||
/>
|
||||
}
|
||||
@if (getSignal(network.strength); as signal) {
|
||||
<tui-icon
|
||||
background="@tui.wifi"
|
||||
[icon]="signal.icon"
|
||||
[style.background]="'var(--tui-background-neutral-2)'"
|
||||
[style.color]="signal.color"
|
||||
/>
|
||||
} @else {
|
||||
<tui-icon icon="@tui.wifi-off" />
|
||||
}
|
||||
</tui-data-list>
|
||||
</button>
|
||||
}
|
||||
</ng-template>
|
||||
@for (network of wifi; track $index) {
|
||||
@if (network.ssid) {
|
||||
@if (network.connected === undefined) {
|
||||
<button tuiCell (click)="prompt(network)">
|
||||
<ng-container
|
||||
*ngTemplateOutlet="row; context: { $implicit: network }"
|
||||
/>
|
||||
</button>
|
||||
} @else {
|
||||
<div tuiCell>
|
||||
<ng-container
|
||||
*ngTemplateOutlet="row; context: { $implicit: network }"
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
styles: `
|
||||
@@ -75,8 +118,6 @@ import { wifiSpec } from './wifi.const'
|
||||
}
|
||||
|
||||
[tuiCell] {
|
||||
padding-inline: 1rem !important;
|
||||
|
||||
&:disabled > * {
|
||||
opacity: 1;
|
||||
}
|
||||
@@ -88,11 +129,24 @@ import { wifiSpec } from './wifi.const'
|
||||
}
|
||||
`,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [TuiCell, TuiTitle, TuiBadge, TuiButton, TuiIcon, TuiFade, i18nPipe],
|
||||
imports: [
|
||||
NgTemplateOutlet,
|
||||
TuiCell,
|
||||
TuiTitle,
|
||||
TuiBadge,
|
||||
TuiButton,
|
||||
TuiIcon,
|
||||
TuiFade,
|
||||
TuiDropdown,
|
||||
TuiDataList,
|
||||
TuiTextfield,
|
||||
i18nPipe,
|
||||
],
|
||||
})
|
||||
export class WifiTableComponent {
|
||||
private readonly loader = inject(LoadingService)
|
||||
private readonly errorService = inject(ErrorService)
|
||||
private readonly dialogs = inject(DialogService)
|
||||
private readonly api = inject(ApiService)
|
||||
private readonly formDialog = inject(FormDialogService)
|
||||
private readonly component = inject(SystemWifiComponent)
|
||||
@@ -102,6 +156,8 @@ export class WifiTableComponent {
|
||||
@Input()
|
||||
wifi: readonly Wifi[] = []
|
||||
|
||||
open = false
|
||||
|
||||
getSignal(signal: number) {
|
||||
if (signal < 5) {
|
||||
return null
|
||||
@@ -141,17 +197,30 @@ export class WifiTableComponent {
|
||||
|
||||
async prompt(network: Wifi): Promise<void> {
|
||||
if (!network.security.length) {
|
||||
await this.component.saveAndConnect(network.ssid)
|
||||
this.dialogs
|
||||
.openConfirm({
|
||||
label: `${this.i18n.transform('Connect to')} ${network.ssid}?`,
|
||||
size: 's',
|
||||
})
|
||||
.pipe(filter(Boolean))
|
||||
.subscribe(() => this.component.saveAndConnect(network.ssid))
|
||||
} else {
|
||||
const ssid = wifiSpec.spec['ssid'] as IST.ValueSpecText
|
||||
const spec: IST.InputSpec = {
|
||||
...wifiSpec.spec,
|
||||
ssid: { ...ssid, disabled: 'ssid', default: network.ssid },
|
||||
}
|
||||
|
||||
this.formDialog.open<FormContext<WiFiForm>>(FormComponent, {
|
||||
label: 'Password needed',
|
||||
data: {
|
||||
spec: wifiSpec.spec,
|
||||
spec,
|
||||
value: { ssid: network.ssid, password: '' },
|
||||
buttons: [
|
||||
{
|
||||
text: this.i18n.transform('Connect')!,
|
||||
handler: async ({ ssid, password }) =>
|
||||
this.component.saveAndConnect(ssid, password),
|
||||
handler: async ({ password }) =>
|
||||
this.component.saveAndConnect(network.ssid, password),
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -8,6 +8,7 @@ import { toSignal } from '@angular/core/rxjs-interop'
|
||||
import { FormsModule } from '@angular/forms'
|
||||
import { RouterLink } from '@angular/router'
|
||||
import {
|
||||
DocsLinkDirective,
|
||||
ErrorService,
|
||||
i18nKey,
|
||||
i18nPipe,
|
||||
@@ -19,11 +20,9 @@ import {
|
||||
TuiAppearance,
|
||||
TuiButton,
|
||||
TuiLoader,
|
||||
TuiNotification,
|
||||
TuiTitle,
|
||||
} from '@taiga-ui/core'
|
||||
import { TuiSwitch } from '@taiga-ui/kit'
|
||||
import { TuiCardLarge, TuiHeader } from '@taiga-ui/layout'
|
||||
import { TuiCardLarge } from '@taiga-ui/layout'
|
||||
import { PatchDB } from 'patch-db-client'
|
||||
import { catchError, defer, map, merge, Observable, of, Subject } from 'rxjs'
|
||||
import {
|
||||
@@ -47,23 +46,20 @@ import { wifiSpec } from './wifi.const'
|
||||
</a>
|
||||
WiFi
|
||||
</ng-container>
|
||||
<header tuiHeader>
|
||||
<tui-notification appearance="negative">
|
||||
<div tuiTitle>
|
||||
{{ 'Deprecated' | i18n }}
|
||||
<div tuiSubtitle>
|
||||
{{
|
||||
'WiFi support will be removed in StartOS v0.4.1. If you do not have access to Ethernet, you can use a WiFi extender to connect to the local network, then connect your server to the extender via Ethernet. Please contact Start9 support with any questions or concerns.'
|
||||
| i18n
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
</tui-notification>
|
||||
</header>
|
||||
@if (status()?.interface) {
|
||||
<section class="g-card">
|
||||
<header>
|
||||
Wi-Fi
|
||||
<a
|
||||
tuiIconButton
|
||||
size="xs"
|
||||
docsLink
|
||||
path="/user-manual/wifi.html"
|
||||
appearance="icon"
|
||||
iconStart="@tui.external-link"
|
||||
>
|
||||
{{ 'Documentation' | i18n }}
|
||||
</a>
|
||||
<input
|
||||
type="checkbox"
|
||||
tuiSwitch
|
||||
@@ -92,8 +88,8 @@ import { wifiSpec } from './wifi.const'
|
||||
></div>
|
||||
}
|
||||
<p>
|
||||
<button tuiButton (click)="other(data)">
|
||||
{{ 'Add' | i18n }}
|
||||
<button tuiButton (click)="other(data)" appearance="flat">
|
||||
+ {{ 'Connect to hidden network' | i18n }}
|
||||
</button>
|
||||
</p>
|
||||
} @else {
|
||||
@@ -128,10 +124,8 @@ import { wifiSpec } from './wifi.const'
|
||||
TitleDirective,
|
||||
RouterLink,
|
||||
PlaceholderComponent,
|
||||
TuiHeader,
|
||||
TuiTitle,
|
||||
TuiNotification,
|
||||
i18nPipe,
|
||||
DocsLinkDirective,
|
||||
],
|
||||
})
|
||||
export default class SystemWifiComponent {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { AsyncPipe } from '@angular/common'
|
||||
import { ChangeDetectionStrategy, Component, inject } from '@angular/core'
|
||||
import { toSignal } from '@angular/core/rxjs-interop'
|
||||
import { RouterModule } from '@angular/router'
|
||||
@@ -6,12 +5,9 @@ import { i18nPipe } from '@start9labs/shared'
|
||||
import { TuiIcon, TuiTitle } from '@taiga-ui/core'
|
||||
import { TuiBadgeNotification } from '@taiga-ui/kit'
|
||||
import { TuiCell } from '@taiga-ui/layout'
|
||||
import { PatchDB } from 'patch-db-client'
|
||||
import { BadgeService } from 'src/app/services/badge.service'
|
||||
import { DataModel } from 'src/app/services/patch-db/data-model'
|
||||
import { TitleDirective } from 'src/app/services/title.service'
|
||||
import { SYSTEM_MENU } from './system.const'
|
||||
import { map } from 'rxjs'
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
@@ -26,9 +22,6 @@ import { map } from 'rxjs'
|
||||
tuiCell="s"
|
||||
routerLinkActive="active"
|
||||
[routerLink]="page.link"
|
||||
[style.display]="
|
||||
!(wifiEnabled$ | async) && page.item === 'WiFi' ? 'none' : null
|
||||
"
|
||||
>
|
||||
<tui-icon [icon]="page.icon" />
|
||||
<span tuiTitle>
|
||||
@@ -116,13 +109,9 @@ import { map } from 'rxjs'
|
||||
TitleDirective,
|
||||
TuiBadgeNotification,
|
||||
i18nPipe,
|
||||
AsyncPipe,
|
||||
],
|
||||
})
|
||||
export class SystemComponent {
|
||||
readonly menu = SYSTEM_MENU
|
||||
readonly badge = toSignal(inject(BadgeService).getCount('system'))
|
||||
readonly wifiEnabled$ = inject<PatchDB<DataModel>>(PatchDB)
|
||||
.watch$('serverInfo', 'network', 'wifi')
|
||||
.pipe(map(wifi => !!wifi.interface && wifi.enabled))
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ export const SYSTEM_MENU = [
|
||||
},
|
||||
{
|
||||
icon: '@tui.mail',
|
||||
item: 'Email',
|
||||
item: 'SMTP',
|
||||
link: 'email',
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user