@@ -75,7 +75,7 @@
@if(settingsForm.dirty || !settingsForm.untouched) {
- @if (formControl.errors?.pattern) {
+ @if (formControl.errors?.emptyOrPattern) {
{{t('ip-address-validation')}}
}
diff --git a/UI/Web/src/app/admin/manage-settings/manage-settings.component.ts b/UI/Web/src/app/admin/manage-settings/manage-settings.component.ts
index 7c669e651..8c5f3f17a 100644
--- a/UI/Web/src/app/admin/manage-settings/manage-settings.component.ts
+++ b/UI/Web/src/app/admin/manage-settings/manage-settings.component.ts
@@ -1,5 +1,5 @@
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, DestroyRef, inject, OnInit} from '@angular/core';
-import {FormControl, FormGroup, ReactiveFormsModule, Validators} from '@angular/forms';
+import {FormControl, FormGroup, ReactiveFormsModule, ValidatorFn, Validators} from '@angular/forms';
import {ToastrService} from 'ngx-toastr';
import {take} from 'rxjs/operators';
import {ServerService} from 'src/app/_services/server.service';
@@ -62,7 +62,7 @@ export class ManageSettingsComponent implements OnInit {
this.settingsForm.addControl('taskScan', new FormControl(this.serverSettings.taskScan, [Validators.required]));
this.settingsForm.addControl('taskBackup', new FormControl(this.serverSettings.taskBackup, [Validators.required]));
this.settingsForm.addControl('taskCleanup', new FormControl(this.serverSettings.taskCleanup, [Validators.required]));
- this.settingsForm.addControl('ipAddresses', new FormControl(this.serverSettings.ipAddresses, [Validators.required, Validators.pattern(ValidIpAddress)]));
+ this.settingsForm.addControl('ipAddresses', new FormControl(this.serverSettings.ipAddresses, [this.emptyOrPattern(ValidIpAddress)]));
this.settingsForm.addControl('port', new FormControl(this.serverSettings.port, [Validators.required]));
this.settingsForm.addControl('loggingLevel', new FormControl(this.serverSettings.loggingLevel, [Validators.required]));
this.settingsForm.addControl('allowStatCollection', new FormControl(this.serverSettings.allowStatCollection, [Validators.required]));
@@ -77,6 +77,7 @@ export class ManageSettingsComponent implements OnInit {
this.settingsForm.addControl('onDeckProgressDays', new FormControl(this.serverSettings.onDeckProgressDays, [Validators.required]));
this.settingsForm.addControl('onDeckUpdateDays', new FormControl(this.serverSettings.onDeckUpdateDays, [Validators.required]));
+
// Automatically save settings as we edit them
this.settingsForm.valueChanges.pipe(
distinctUntilChanged(),
@@ -186,4 +187,19 @@ export class ManageSettingsComponent implements OnInit {
console.error('error: ', err);
});
}
+
+ emptyOrPattern(pattern: RegExp): ValidatorFn {
+ return (control) => {
+ if (!control.value || control.value.length === 0) {
+ return null;
+ }
+
+ if (pattern.test(control.value)) {
+ return null;
+ }
+
+ return { 'emptyOrPattern': { 'requiredPattern': pattern.toString(), 'actualValue': control.value } };
+ }
+ }
+
}
diff --git a/UI/Web/src/assets/langs/fi.json b/UI/Web/src/assets/langs/fi.json
index edcd8166f..9a316f77a 100644
--- a/UI/Web/src/assets/langs/fi.json
+++ b/UI/Web/src/assets/langs/fi.json
@@ -10,7 +10,7 @@
"devices-tab": "{{tabs.devices-tab}}",
"smart-filters-tab": "{{tabs.smart-filters-tab}}",
"success-toast": "Käyttäjäasetukset päivitetty",
- "global-settings-title": "Laajamittaiset asetukset",
+ "global-settings-title": "Yleisesti pätevät asetukset",
"page-layout-mode-label": "Sivun asettelutila",
"page-layout-mode-tooltip": "Näytä kohteet kortteina tai luettelonäkymänä Sarjojen yksityiskohdat -sivulla.",
"locale-label": "Kieliasetus",
diff --git a/UI/Web/src/assets/langs/zh_Hans.json b/UI/Web/src/assets/langs/zh_Hans.json
index d3a8496e0..a81869f69 100644
--- a/UI/Web/src/assets/langs/zh_Hans.json
+++ b/UI/Web/src/assets/langs/zh_Hans.json
@@ -2219,12 +2219,12 @@
"delete-device": "您确定要删除该设备吗?",
"confirm-regen-covers": "刷新封面将强制重新生成所有封面图片。这是一项繁重的运算。您确定执行,而不想使用扫描操作代替吗?",
"alert-long-running": "这是一个长时间运行的任务。请等待其完成后再次进行操作。",
- "confirm-delete-multiple-series": "您确定要删除{{count}}个系列吗?这不会修改磁盘上的文件。",
+ "confirm-delete-multiple-series": "您确定要删除这 {{count}} 个系列吗?这不会修改磁盘上的文件。",
"confirm-delete-series": "您确定要删除此系列吗?这不会修改磁盘上的文件。",
"confirm-delete-chapter": "您确定要删除此章节吗?它不会修改磁盘上的文件。",
"confirm-delete-volume": "您确定要删除此卷吗?它不会修改磁盘上的文件。",
"alert-bad-theme": "主题中存在无效或不安全的CSS。请联系管理员进行修正。将默认为暗色主题。",
- "confirm-library-delete": "您确定要删除{{name}}资料库吗?此操作无法撤销。",
+ "confirm-library-delete": "您确定要删除 {{name}} 资料库吗?此操作无法撤销。",
"confirm-library-type-change": "更改资料库类型将触发具有不同解析规则的新扫描,并可能导致重新创建系列,因此您可能会丢失进度和书签。您应该在执行此操作之前进行备份。您确定要继续吗?",
"confirm-download-size": "{{entityType}}的大小为{{size}}。确定要继续吗?",
"confirm-download-size-ios": "iOS 在下载大于 200MB 的文件时出现问题,此下载可能无法完成。",