Fix auth, Bootstrap, Blazor nav, LDAP, and deployment pipeline for working Central UI
Bootstrap served locally with absolute paths and <base href="/">. LDAP auth uses search-then-bind with service account for GLAuth compatibility. CookieAuthenticationStateProvider reads HttpContext.User instead of parsing JWT. Login/logout forms opt out of Blazor enhanced nav (data-enhance="false"). Nav links use absolute paths; seed data includes Design/Deployment group mappings. DataConnections page loads all connections (not just site-assigned). Site appsettings configured for Test Plant A; Site registers with Central on startup. DeploymentService resolves string site identifier for Akka routing. Instances page gains Create Instance form.
This commit is contained in:
@@ -199,17 +199,15 @@
|
||||
try
|
||||
{
|
||||
_sites = (await SiteRepository.GetAllSitesAsync()).ToList();
|
||||
_connections = (await SiteRepository.GetAllDataConnectionsAsync()).ToList();
|
||||
|
||||
// Load all connections by iterating all sites and collecting unique connections
|
||||
var allConnections = new Dictionary<int, DataConnection>();
|
||||
// Load site assignments for each connection
|
||||
_connectionSites.Clear();
|
||||
|
||||
foreach (var site in _sites)
|
||||
{
|
||||
var siteConns = await SiteRepository.GetDataConnectionsBySiteIdAsync(site.Id);
|
||||
foreach (var conn in siteConns)
|
||||
{
|
||||
allConnections[conn.Id] = conn;
|
||||
if (!_connectionSites.ContainsKey(conn.Id))
|
||||
_connectionSites[conn.Id] = new List<SiteDataConnectionAssignment>();
|
||||
|
||||
@@ -218,8 +216,6 @@
|
||||
_connectionSites[conn.Id].Add(assignment);
|
||||
}
|
||||
}
|
||||
|
||||
_connections = allConnections.Values.OrderBy(c => c.Name).ToList();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -7,15 +7,18 @@
|
||||
@using ScadaLink.Commons.Interfaces.Repositories
|
||||
@using ScadaLink.Commons.Types.Enums
|
||||
@using ScadaLink.DeploymentManager
|
||||
@using ScadaLink.TemplateEngine.Services
|
||||
@attribute [Authorize(Policy = AuthorizationPolicies.RequireDeployment)]
|
||||
@inject ITemplateEngineRepository TemplateEngineRepository
|
||||
@inject ISiteRepository SiteRepository
|
||||
@inject IDeploymentManagerRepository DeploymentManagerRepository
|
||||
@inject DeploymentService DeploymentService
|
||||
@inject InstanceService InstanceService
|
||||
|
||||
<div class="container-fluid mt-3">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h4 class="mb-0">Instances</h4>
|
||||
<button class="btn btn-primary btn-sm" @onclick="ShowCreateForm">Create Instance</button>
|
||||
</div>
|
||||
|
||||
<ToastNotification @ref="_toast" />
|
||||
@@ -31,6 +34,49 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
@if (_showCreateForm)
|
||||
{
|
||||
<div class="card mb-3">
|
||||
<div class="card-body">
|
||||
<h6 class="card-title">Create Instance</h6>
|
||||
<div class="row g-2 align-items-end">
|
||||
<div class="col-md-3">
|
||||
<label class="form-label small">Instance Name</label>
|
||||
<input type="text" class="form-control form-control-sm" @bind="_createName" placeholder="e.g. Motor-1" />
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label small">Template</label>
|
||||
<select class="form-select form-select-sm" @bind="_createTemplateId">
|
||||
<option value="0">Select template...</option>
|
||||
@foreach (var t in _templates)
|
||||
{
|
||||
<option value="@t.Id">@t.Name</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label small">Site</label>
|
||||
<select class="form-select form-select-sm" @bind="_createSiteId">
|
||||
<option value="0">Select site...</option>
|
||||
@foreach (var s in _sites)
|
||||
{
|
||||
<option value="@s.Id">@s.Name</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<button class="btn btn-success btn-sm me-1" @onclick="CreateInstance">Create</button>
|
||||
<button class="btn btn-outline-secondary btn-sm" @onclick="() => _showCreateForm = false">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
@if (_createError != null)
|
||||
{
|
||||
<div class="text-danger small mt-1">@_createError</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@* Filters *@
|
||||
<div class="row mb-3 g-2">
|
||||
<div class="col-md-2">
|
||||
@@ -365,4 +411,48 @@
|
||||
}
|
||||
_actionInProgress = false;
|
||||
}
|
||||
|
||||
// Create instance form
|
||||
private bool _showCreateForm;
|
||||
private string _createName = string.Empty;
|
||||
private int _createTemplateId;
|
||||
private int _createSiteId;
|
||||
private string? _createError;
|
||||
|
||||
private void ShowCreateForm()
|
||||
{
|
||||
_createName = string.Empty;
|
||||
_createTemplateId = 0;
|
||||
_createSiteId = 0;
|
||||
_createError = null;
|
||||
_showCreateForm = true;
|
||||
}
|
||||
|
||||
private async Task CreateInstance()
|
||||
{
|
||||
_createError = null;
|
||||
if (string.IsNullOrWhiteSpace(_createName)) { _createError = "Instance name is required."; return; }
|
||||
if (_createTemplateId == 0) { _createError = "Select a template."; return; }
|
||||
if (_createSiteId == 0) { _createError = "Select a site."; return; }
|
||||
|
||||
try
|
||||
{
|
||||
var result = await InstanceService.CreateInstanceAsync(
|
||||
_createName.Trim(), _createTemplateId, _createSiteId, null, "system");
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
_showCreateForm = false;
|
||||
_toast.ShowSuccess($"Instance '{_createName}' created.");
|
||||
await LoadDataAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
_createError = result.Error;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_createError = $"Create failed: {ex.Message}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<div class="alert alert-danger py-2" role="alert">@ErrorMessage</div>
|
||||
}
|
||||
|
||||
<form method="post" action="/auth/login">
|
||||
<form method="post" action="/auth/login" data-enhance="false">
|
||||
<div class="mb-3">
|
||||
<label for="username" class="form-label">Username</label>
|
||||
<input type="text" class="form-control" id="username" name="username"
|
||||
|
||||
Reference in New Issue
Block a user