2b5dabb336
Areas page now shows a single TreeView with sites as roots and areas as children. Context menus: sites get "Add Area", areas get "Add Child Area", "Edit Area", "Delete Area" — each navigating to a dedicated page. The Delete Area page shows a TreeView of the area and all recursive children with assigned instances. Deletion is blocked if any instances are assigned to the area or its descendants.
96 lines
2.7 KiB
Plaintext
96 lines
2.7 KiB
Plaintext
@page "/admin/areas/{Id:int}/edit"
|
|
@using ScadaLink.Security
|
|
@using ScadaLink.Commons.Entities.Instances
|
|
@using ScadaLink.Commons.Interfaces.Repositories
|
|
@attribute [Authorize(Policy = AuthorizationPolicies.RequireDesign)]
|
|
@inject ITemplateEngineRepository TemplateEngineRepository
|
|
@inject NavigationManager NavigationManager
|
|
|
|
<div class="container-fluid mt-3">
|
|
<div class="d-flex align-items-center mb-3">
|
|
<a href="/admin/areas" class="btn btn-outline-secondary btn-sm me-3">← Back</a>
|
|
<h4 class="mb-0">Edit Area</h4>
|
|
</div>
|
|
|
|
<ToastNotification @ref="_toast" />
|
|
|
|
@if (_loading)
|
|
{
|
|
<LoadingSpinner IsLoading="true" />
|
|
}
|
|
else if (_errorMessage != null)
|
|
{
|
|
<div class="alert alert-danger">@_errorMessage</div>
|
|
}
|
|
else
|
|
{
|
|
<div class="card" style="max-width: 500px;">
|
|
<div class="card-body">
|
|
<div class="mb-3">
|
|
<label class="form-label small">Name</label>
|
|
<input type="text" class="form-control form-control-sm" @bind="_name" />
|
|
</div>
|
|
@if (_formError != null)
|
|
{
|
|
<div class="text-danger small mb-2">@_formError</div>
|
|
}
|
|
<button class="btn btn-success btn-sm" @onclick="Save" disabled="@_saving">Save</button>
|
|
</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
|
|
@code {
|
|
[Parameter] public int Id { get; set; }
|
|
|
|
private Area? _area;
|
|
private string _name = string.Empty;
|
|
private string? _formError;
|
|
private string? _errorMessage;
|
|
private bool _loading = true;
|
|
private bool _saving;
|
|
|
|
private ToastNotification _toast = default!;
|
|
|
|
protected override async Task OnInitializedAsync()
|
|
{
|
|
try
|
|
{
|
|
_area = await TemplateEngineRepository.GetAreaByIdAsync(Id);
|
|
if (_area == null)
|
|
{
|
|
_errorMessage = $"Area #{Id} not found.";
|
|
}
|
|
else
|
|
{
|
|
_name = _area.Name;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_errorMessage = $"Failed to load area: {ex.Message}";
|
|
}
|
|
_loading = false;
|
|
}
|
|
|
|
private async Task Save()
|
|
{
|
|
_formError = null;
|
|
if (string.IsNullOrWhiteSpace(_name)) { _formError = "Name is required."; return; }
|
|
|
|
_saving = true;
|
|
try
|
|
{
|
|
_area!.Name = _name.Trim();
|
|
await TemplateEngineRepository.UpdateAreaAsync(_area);
|
|
await TemplateEngineRepository.SaveChangesAsync();
|
|
NavigationManager.NavigateTo("/admin/areas");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_formError = $"Save failed: {ex.Message}";
|
|
}
|
|
_saving = false;
|
|
}
|
|
}
|