feat(settings): set nest server URL from Options

This commit is contained in:
aj committed 2026-10-09 21:54:10 -04:00
1 parent 1c6d02c480
commit 69304d3851
6 files changed
+114 -3

No files matched your search

+12
View File
@@ -32,6 +32,18 @@ public sealed class NestStorageSettings
public bool IsDatabaseMode =>
Mode == NestStorageMode.Database && !string.IsNullOrWhiteSpace(ServerUrl);
/// <summary>Validate and normalize a nest server base URL without changing storage mode.</summary>
public static bool TryNormalizeServerUrl(string? url, out string normalized)
{
normalized = NormalizeUrl(url);
if (Uri.TryCreate(normalized, UriKind.Absolute, out var uri)
&& (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps))
return true;
normalized = "";
return false;
}
/// <summary>%APPDATA%\OpenNest\storage.json.</summary>
public static string DefaultPath => Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
+25
View File
@@ -59,6 +59,31 @@ public class NestStorageSettingsTests : IDisposable
Assert.False(settings.IsDatabaseMode);
}
[Fact]
public void TryNormalizeServerUrl_AcceptsHttpsWithoutChangingMode()
{
var settings = new NestStorageSettings { Mode = NestStorageMode.File };
Assert.True(NestStorageSettings.TryNormalizeServerUrl(" https://shop.example:8090/ ", out var url));
settings.ServerUrl = url;
settings.Save(FilePath);
var loaded = NestStorageSettings.Load(FilePath);
Assert.Equal("https://shop.example:8090", loaded.ServerUrl);
Assert.Equal(NestStorageMode.File, loaded.Mode);
Assert.False(loaded.IsDatabaseMode);
}
[Theory]
[InlineData("")]
[InlineData("ftp://shop.example")]
[InlineData("not-a-url")]
public void TryNormalizeServerUrl_RejectsInvalidAddress(string input)
{
Assert.False(NestStorageSettings.TryNormalizeServerUrl(input, out var url));
Assert.Equal("", url);
}
public void Dispose()
{
if (Directory.Exists(_directory))
+6
View File
@@ -646,6 +646,7 @@ namespace OpenNest.Forms
var serverUrl = NestStorage.Settings.ServerUrl;
databaseOpenInProgress = true;
storageModeMenu.Enabled = false;
mnuToolsOptions.Enabled = false;
var file = await repository.GetFileAsync(dlg.SelectedId);
if (file == null)
throw new FileNotFoundException("This nest no longer exists on the server.");
@@ -663,7 +664,10 @@ namespace OpenNest.Forms
{
databaseOpenInProgress = false;
if (!IsDisposed)
{
storageModeMenu.Enabled = !databaseSaveInProgress;
mnuToolsOptions.Enabled = !databaseSaveInProgress;
}
}
}
@@ -707,6 +711,7 @@ namespace OpenNest.Forms
{
databaseSaveInProgress = true;
storageModeMenu.Enabled = false;
mnuToolsOptions.Enabled = false;
EnableCheck();
try
{
@@ -729,6 +734,7 @@ namespace OpenNest.Forms
if (!IsDisposed)
{
storageModeMenu.Enabled = !databaseOpenInProgress;
mnuToolsOptions.Enabled = !databaseOpenInProgress;
EnableCheck();
}
}
+42 -3
View File
@@ -41,9 +41,13 @@
this.strategyGroupBox = new System.Windows.Forms.GroupBox();
this.colorSchemeLabel = new System.Windows.Forms.Label();
this.colorSchemeCombo = new System.Windows.Forms.ComboBox();
this.serverGroupBox = new System.Windows.Forms.GroupBox();
this.serverUrlBox = new System.Windows.Forms.TextBox();
this.setServerButton = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).BeginInit();
this.tableLayoutPanel1.SuspendLayout();
this.bottomPanel1.SuspendLayout();
this.serverGroupBox.SuspendLayout();
this.SuspendLayout();
//
// checkBox1
@@ -135,7 +139,7 @@
this.bottomPanel1.Controls.Add(this.cancelButton);
this.bottomPanel1.Controls.Add(this.saveButton);
this.bottomPanel1.Dock = System.Windows.Forms.DockStyle.Bottom;
this.bottomPanel1.Location = new System.Drawing.Point(0, 368);
this.bottomPanel1.Location = new System.Drawing.Point(0, 443);
this.bottomPanel1.Name = "bottomPanel1";
this.bottomPanel1.Size = new System.Drawing.Size(708, 50);
this.bottomPanel1.TabIndex = 1;
@@ -158,7 +162,7 @@
// strategyGroupBox
//
this.strategyGroupBox.Controls.Add(this.strategyGrid);
this.strategyGroupBox.Location = new System.Drawing.Point(12, 178);
this.strategyGroupBox.Location = new System.Drawing.Point(12, 253);
this.strategyGroupBox.Name = "strategyGroupBox";
this.strategyGroupBox.Size = new System.Drawing.Size(684, 180);
this.strategyGroupBox.TabIndex = 2;
@@ -184,13 +188,43 @@
this.colorSchemeCombo.Size = new System.Drawing.Size(130, 24);
this.colorSchemeCombo.TabIndex = 11;
//
// serverGroupBox
//
this.serverGroupBox.Controls.Add(this.serverUrlBox);
this.serverGroupBox.Controls.Add(this.setServerButton);
this.serverGroupBox.Location = new System.Drawing.Point(12, 178);
this.serverGroupBox.Name = "serverGroupBox";
this.serverGroupBox.Size = new System.Drawing.Size(684, 69);
this.serverGroupBox.TabIndex = 1;
this.serverGroupBox.TabStop = false;
this.serverGroupBox.Text = "Nest server URL (File / Database mode is selected under File > Storage Mode)";
//
// serverUrlBox
//
this.serverUrlBox.Location = new System.Drawing.Point(12, 29);
this.serverUrlBox.Name = "serverUrlBox";
this.serverUrlBox.PlaceholderText = "http://server:8090";
this.serverUrlBox.Size = new System.Drawing.Size(485, 22);
this.serverUrlBox.TabIndex = 0;
//
// setServerButton
//
this.setServerButton.Location = new System.Drawing.Point(504, 26);
this.setServerButton.Name = "setServerButton";
this.setServerButton.Size = new System.Drawing.Size(168, 28);
this.setServerButton.TabIndex = 1;
this.setServerButton.Text = "Set / Change Server";
this.setServerButton.UseVisualStyleBackColor = true;
this.setServerButton.Click += new System.EventHandler(this.SetServer_Click);
//
// OptionsForm
//
this.AcceptButton = this.saveButton;
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.CancelButton = this.cancelButton;
this.ClientSize = new System.Drawing.Size(708, 418);
this.ClientSize = new System.Drawing.Size(708, 493);
this.Controls.Add(this.strategyGroupBox);
this.Controls.Add(this.serverGroupBox);
this.Controls.Add(this.tableLayoutPanel1);
this.Controls.Add(this.bottomPanel1);
this.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
@@ -206,6 +240,8 @@
this.tableLayoutPanel1.ResumeLayout(false);
this.tableLayoutPanel1.PerformLayout();
this.bottomPanel1.ResumeLayout(false);
this.serverGroupBox.ResumeLayout(false);
this.serverGroupBox.PerformLayout();
this.ResumeLayout(false);
}
@@ -224,5 +260,8 @@
private System.Windows.Forms.GroupBox strategyGroupBox;
private System.Windows.Forms.Label colorSchemeLabel;
private System.Windows.Forms.ComboBox colorSchemeCombo;
private System.Windows.Forms.GroupBox serverGroupBox;
private System.Windows.Forms.TextBox serverUrlBox;
private System.Windows.Forms.Button setServerButton;
}
}
+25
View File
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using OpenNest.Data;
using OpenNest.Engine.Strategies;
using OpenNest.Properties;
@@ -72,6 +73,7 @@ namespace OpenNest.Forms
private void LoadSettings()
{
serverUrlBox.Text = NestStorage.Settings.ServerUrl;
checkBox1.Checked = Settings.Default.CreateNewNestOnOpen;
numericUpDown1.Value = (decimal)Settings.Default.AutoSizePlateFactor;
@@ -142,5 +144,28 @@ namespace OpenNest.Forms
{
SaveSettings();
}
private void SetServer_Click(object sender, EventArgs e)
{
if (!NestStorageSettings.TryNormalizeServerUrl(serverUrlBox.Text, out var url))
{
MessageBox.Show(this, "Enter a valid http or https server URL.",
"Server URL", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
try
{
NestStorage.Save(NestStorage.Settings.Mode, url);
serverUrlBox.Text = NestStorage.Settings.ServerUrl;
MessageBox.Show(this, "Server URL saved. Storage mode has not changed.",
"Server URL", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show(this, $"Could not save the server URL: {ex.Message}",
"Server URL", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
+4
View File
@@ -241,6 +241,10 @@ curl --fail http://<bind-address>:<port>/healthz # {"status":"ok"}
In the desktop app choose **File > Storage Mode...**, Database, and enter the base
URL `http://<bind-address>:<port>`, without `/healthz` or `/api/nests`.
To set or change just the saved server address without changing File/Database mode,
use **Tools > Options > Nest server URL > Set / Change Server**. This saves the URL
immediately, independently of the Options Save button; it does not migrate nests
or enable Database mode. Canceling Options afterward does not undo that address.
### Backup, restore, and upgrade