remove non option from smtp for better package compat

This commit is contained in:
Matt Hill
2026-03-06 00:06:18 -07:00
parent 7693b0febc
commit 59155c2e34
8 changed files with 58 additions and 28 deletions

View File

@@ -84,10 +84,6 @@ export const customSmtp = smtpFields()
* Each variant has SMTP fields pre-filled with the provider's recommended settings. * Each variant has SMTP fields pre-filled with the provider's recommended settings.
*/ */
export const smtpProviderVariants = Variants.of({ export const smtpProviderVariants = Variants.of({
none: {
name: 'None',
spec: InputSpec.of({}),
},
gmail: { gmail: {
name: 'Gmail', name: 'Gmail',
spec: smtpFields({ spec: smtpFields({
@@ -140,7 +136,7 @@ export const smtpProviderVariants = Variants.of({
export const systemSmtpSpec = InputSpec.of({ export const systemSmtpSpec = InputSpec.of({
provider: Value.union({ provider: Value.union({
name: 'Provider', name: 'Provider',
default: 'none', default: 'gmail',
variants: smtpProviderVariants, variants: smtpProviderVariants,
}), }),
}) })

View File

@@ -360,7 +360,6 @@ export default {
377: 'StartOS-Sicherungen erkannt', 377: 'StartOS-Sicherungen erkannt',
378: 'Keine StartOS-Sicherungen erkannt', 378: 'Keine StartOS-Sicherungen erkannt',
379: 'StartOS-Version', 379: 'StartOS-Version',
381: 'SMTP-Zugangsdaten',
382: 'Test-E-Mail senden', 382: 'Test-E-Mail senden',
383: 'Senden', 383: 'Senden',
384: 'E-Mail wird gesendet', 384: 'E-Mail wird gesendet',

View File

@@ -359,7 +359,6 @@ export const ENGLISH: Record<string, number> = {
'StartOS backups detected': 377, 'StartOS backups detected': 377,
'No StartOS backups detected': 378, 'No StartOS backups detected': 378,
'StartOS Version': 379, 'StartOS Version': 379,
'SMTP Credentials': 381,
'Send test email': 382, 'Send test email': 382,
'Send': 383, 'Send': 383,
'Sending email': 384, 'Sending email': 384,

View File

@@ -360,7 +360,6 @@ export default {
377: 'Copias de seguridad de StartOS detectadas', 377: 'Copias de seguridad de StartOS detectadas',
378: 'No se detectaron copias de seguridad de StartOS', 378: 'No se detectaron copias de seguridad de StartOS',
379: 'Versión de StartOS', 379: 'Versión de StartOS',
381: 'Credenciales SMTP',
382: 'Enviar correo de prueba', 382: 'Enviar correo de prueba',
383: 'Enviar', 383: 'Enviar',
384: 'Enviando correo', 384: 'Enviando correo',

View File

@@ -360,7 +360,6 @@ export default {
377: 'Sauvegardes StartOS détectées', 377: 'Sauvegardes StartOS détectées',
378: 'Aucune sauvegarde StartOS détectée', 378: 'Aucune sauvegarde StartOS détectée',
379: 'Version de StartOS', 379: 'Version de StartOS',
381: 'Identifiants SMTP',
382: 'Envoyer un email de test', 382: 'Envoyer un email de test',
383: 'Envoyer', 383: 'Envoyer',
384: 'Envoi de lemail', 384: 'Envoi de lemail',

View File

@@ -360,7 +360,6 @@ export default {
377: 'Wykryto kopie zapasowe StartOS', 377: 'Wykryto kopie zapasowe StartOS',
378: 'Nie wykryto kopii zapasowych StartOS', 378: 'Nie wykryto kopii zapasowych StartOS',
379: 'Wersja StartOS', 379: 'Wersja StartOS',
381: 'Dane logowania SMTP',
382: 'Wyślij e-mail testowy', 382: 'Wyślij e-mail testowy',
383: 'Wyślij', 383: 'Wyślij',
384: 'Wysyłanie e-maila', 384: 'Wysyłanie e-maila',

View File

@@ -10,7 +10,7 @@ import {
i18nPipe, i18nPipe,
LoadingService, LoadingService,
} from '@start9labs/shared' } from '@start9labs/shared'
import { inputSpec, utils } from '@start9labs/start-sdk' import { inputSpec, ISB, utils } from '@start9labs/start-sdk'
import { TuiButton, TuiError, TuiTextfield, TuiTitle } from '@taiga-ui/core' import { TuiButton, TuiError, TuiTextfield, TuiTitle } from '@taiga-ui/core'
import { TuiHeader } from '@taiga-ui/layout' import { TuiHeader } from '@taiga-ui/layout'
import { PatchDB } from 'patch-db-client' import { PatchDB } from 'patch-db-client'
@@ -43,14 +43,14 @@ function detectProviderKey(host: string | undefined): string {
<a routerLink=".." tuiIconButton iconStart="@tui.arrow-left"> <a routerLink=".." tuiIconButton iconStart="@tui.arrow-left">
{{ 'Back' | i18n }} {{ 'Back' | i18n }}
</a> </a>
{{ 'SMTP' | i18n }} SMTP
</ng-container> </ng-container>
@if (form$ | async; as data) { @if (form$ | async; as data) {
<form [formGroup]="data.form"> <form [formGroup]="data.form">
<header tuiHeader="body-l"> <header tuiHeader="body-l">
<h3 tuiTitle> <h3 tuiTitle>
<b> <b>
{{ 'SMTP Credentials' | i18n }} SMTP
<a <a
tuiIconButton tuiIconButton
size="xs" size="xs"
@@ -66,6 +66,16 @@ function detectProviderKey(host: string | undefined): string {
</header> </header>
<form-group [spec]="data.spec" /> <form-group [spec]="data.spec" />
<footer> <footer>
@if (!data.form.pristine) {
<button
tuiButton
size="l"
appearance="secondary"
(click)="cancel(data)"
>
{{ 'Cancel' | i18n }}
</button>
}
<button <button
tuiButton tuiButton
size="l" size="l"
@@ -76,7 +86,7 @@ function detectProviderKey(host: string | undefined): string {
</button> </button>
</footer> </footer>
</form> </form>
@if (data.form.value.provider?.selection !== 'none') { @if (data.form.value.smtp?.selection === 'enabled') {
<form> <form>
<header tuiHeader="body-l"> <header tuiHeader="body-l">
<h3 tuiTitle> <h3 tuiTitle>
@@ -163,12 +173,32 @@ export default class SystemEmailComponent {
return !!value && !this.emailRegex.test(value) return !!value && !this.emailRegex.test(value)
} }
private readonly smtpSpec = ISB.InputSpec.of({
smtp: ISB.Value.union({
name: this.i18n.transform('SMTP'),
default: 'disabled',
variants: ISB.Variants.of({
disabled: {
name: this.i18n.transform('Disabled'),
spec: ISB.InputSpec.of({}),
},
enabled: {
name: this.i18n.transform('Enabled'),
spec: inputSpec.constants.systemSmtpSpec,
},
}),
}),
})
readonly form$ = this.patch.watch$('serverInfo', 'smtp').pipe( readonly form$ = this.patch.watch$('serverInfo', 'smtp').pipe(
switchMap(async value => { switchMap(async value => {
const spec = await configBuilderToSpec(inputSpec.constants.systemSmtpSpec) const spec = await configBuilderToSpec(this.smtpSpec)
const formData = value const formData = value
? { ? {
smtp: {
selection: 'enabled' as const,
value: {
provider: { provider: {
selection: detectProviderKey(value.host), selection: detectProviderKey(value.host),
value: { value: {
@@ -182,16 +212,18 @@ export default class SystemEmailComponent {
password: value.password, password: value.password,
}, },
}, },
},
},
} }
: undefined : undefined
const form = this.formService.createForm(spec, formData) const form = this.formService.createForm(spec, formData)
return { form, spec } return { form, spec, formData }
}), }),
) )
private getSmtpValue(formValue: Record<string, any>) { private getSmtpValue(formValue: Record<string, any>) {
const { security, ...rest } = formValue['provider'].value const { security, ...rest } = formValue['smtp'].value.provider.value
return { return {
...rest, ...rest,
security: security.selection, security: security.selection,
@@ -203,7 +235,7 @@ export default class SystemEmailComponent {
const loader = this.loader.open('Saving').subscribe() const loader = this.loader.open('Saving').subscribe()
try { try {
if (formValue['provider'].selection === 'none') { if (formValue['smtp'].selection === 'disabled') {
await this.api.clearSmtp({}) await this.api.clearSmtp({})
} else { } else {
await this.api.setSmtp(this.getSmtpValue(formValue)) await this.api.setSmtp(this.getSmtpValue(formValue))
@@ -215,6 +247,13 @@ export default class SystemEmailComponent {
} }
} }
cancel(data: {
form: ReturnType<FormService['createForm']>
formData: Record<string, any> | undefined
}) {
data.form.reset(data.formData)
}
async sendTestEmail(formValue: Record<string, any>) { async sendTestEmail(formValue: Record<string, any>) {
const smtpValue = this.getSmtpValue(formValue) const smtpValue = this.getSmtpValue(formValue)
const address = this.testEmailControl.value! const address = this.testEmailControl.value!

View File

@@ -28,7 +28,7 @@ export default [
{ {
path: 'email', path: 'email',
title: titleResolver, title: titleResolver,
loadComponent: () => import('./routes/email/email.component'), loadComponent: () => import('./routes/smtp/smtp.component'),
}, },
{ {
path: 'backup', path: 'backup',