chore: organize solution into module folders (Core/Server/Drivers/Client/Tooling)
Group all 69 projects into category subfolders under src/ and tests/ so the Rider Solution Explorer mirrors the module structure. Folders: Core, Server, Drivers (with a nested Driver CLIs subfolder), Client, Tooling. - Move every project folder on disk with git mv (history preserved as renames). - Recompute relative paths in 57 .csproj files: cross-category ProjectReferences, the lib/ HintPath+None refs in Driver.Historian.Wonderware, and the external mxaccessgw refs in Driver.Galaxy and its test project. - Rebuild ZB.MOM.WW.OtOpcUa.slnx with nested solution folders. - Re-prefix project paths in functional scripts (e2e, compliance, smoke SQL, integration, install). Build green (0 errors); unit tests pass. Docs left for a separate pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
@page "/clusters/new"
|
||||
@using System.ComponentModel.DataAnnotations
|
||||
@using ZB.MOM.WW.OtOpcUa.Admin.Services
|
||||
@using ZB.MOM.WW.OtOpcUa.Configuration.Entities
|
||||
@using ZB.MOM.WW.OtOpcUa.Configuration.Enums
|
||||
@inject ClusterService ClusterSvc
|
||||
@inject GenerationService GenerationSvc
|
||||
@inject NavigationManager Nav
|
||||
|
||||
<h1 class="mb-4">New cluster</h1>
|
||||
|
||||
<EditForm Model="_input" OnValidSubmit="CreateAsync" FormName="new-cluster">
|
||||
<DataAnnotationsValidator/>
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">ClusterId <span class="text-danger">*</span></label>
|
||||
<InputText @bind-Value="_input.ClusterId" class="form-control"/>
|
||||
<div class="form-text">Stable internal ID. Lowercase alphanumeric + hyphens; ≤ 64 chars.</div>
|
||||
<ValidationMessage For="() => _input.ClusterId"/>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Display name <span class="text-danger">*</span></label>
|
||||
<InputText @bind-Value="_input.Name" class="form-control"/>
|
||||
<ValidationMessage For="() => _input.Name"/>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Enterprise</label>
|
||||
<InputText @bind-Value="_input.Enterprise" class="form-control"/>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Site</label>
|
||||
<InputText @bind-Value="_input.Site" class="form-control"/>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Redundancy</label>
|
||||
<InputSelect @bind-Value="_input.RedundancyMode" class="form-select">
|
||||
<option value="@RedundancyMode.None">None (single node)</option>
|
||||
<option value="@RedundancyMode.Warm">Warm (2 nodes)</option>
|
||||
<option value="@RedundancyMode.Hot">Hot (2 nodes)</option>
|
||||
</InputSelect>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (!string.IsNullOrEmpty(_error))
|
||||
{
|
||||
<div class="alert alert-danger mt-3">@_error</div>
|
||||
}
|
||||
|
||||
<div class="mt-4">
|
||||
<button type="submit" class="btn btn-primary" disabled="@_submitting">Create cluster</button>
|
||||
<a href="/clusters" class="btn btn-secondary ms-2">Cancel</a>
|
||||
</div>
|
||||
</EditForm>
|
||||
|
||||
@code {
|
||||
private sealed class Input
|
||||
{
|
||||
[Required, RegularExpression("^[a-z0-9-]{1,64}$", ErrorMessage = "Lowercase alphanumeric + hyphens only")]
|
||||
public string ClusterId { get; set; } = string.Empty;
|
||||
|
||||
[Required, StringLength(128)]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
[StringLength(32)] public string Enterprise { get; set; } = "zb";
|
||||
[StringLength(32)] public string Site { get; set; } = "dev";
|
||||
public RedundancyMode RedundancyMode { get; set; } = RedundancyMode.None;
|
||||
}
|
||||
|
||||
private Input _input = new();
|
||||
private bool _submitting;
|
||||
private string? _error;
|
||||
|
||||
private async Task CreateAsync()
|
||||
{
|
||||
_submitting = true;
|
||||
_error = null;
|
||||
|
||||
try
|
||||
{
|
||||
var cluster = new ServerCluster
|
||||
{
|
||||
ClusterId = _input.ClusterId,
|
||||
Name = _input.Name,
|
||||
Enterprise = _input.Enterprise,
|
||||
Site = _input.Site,
|
||||
RedundancyMode = _input.RedundancyMode,
|
||||
NodeCount = _input.RedundancyMode == RedundancyMode.None ? (byte)1 : (byte)2,
|
||||
Enabled = true,
|
||||
CreatedBy = "admin-ui",
|
||||
};
|
||||
|
||||
await ClusterSvc.CreateAsync(cluster, createdBy: "admin-ui", CancellationToken.None);
|
||||
await GenerationSvc.CreateDraftAsync(cluster.ClusterId, createdBy: "admin-ui", CancellationToken.None);
|
||||
|
||||
Nav.NavigateTo($"/clusters/{cluster.ClusterId}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_error = ex.Message;
|
||||
}
|
||||
finally { _submitting = false; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user