Files
ScadaBridge/src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Pages/Design/TemplateCreate.razor
T

128 lines
4.3 KiB
Plaintext

@page "/design/templates/create"
@using ZB.MOM.WW.ScadaBridge.CentralUI.Services
@using ZB.MOM.WW.ScadaBridge.Security
@using ZB.MOM.WW.ScadaBridge.Commons.Entities.Templates
@using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Repositories
@using ZB.MOM.WW.ScadaBridge.TemplateEngine
@attribute [Authorize(Policy = AuthorizationPolicies.RequireDesign)]
@inject ITemplateEngineRepository TemplateEngineRepository
@inject TemplateService TemplateService
@inject AuthenticationStateProvider AuthStateProvider
@inject NavigationManager NavigationManager
<div class="container-fluid mt-3">
<div class="mb-3">
<button class="btn btn-outline-secondary btn-sm"
aria-label="Back to Templates"
@onclick="GoBack">← Back</button>
</div>
<h4 class="mb-3">Create Template</h4>
@if (_loading)
{
<LoadingSpinner IsLoading="true" />
}
else
{
<div class="card">
<div class="card-body">
<div class="mb-3">
<label class="form-label">Name</label>
<input type="text" class="form-control" @bind="_createName" />
</div>
<div class="mb-3">
<label class="form-label">Parent Template</label>
<select class="form-select" @bind="_createParentId">
<option value="0">(None - root template)</option>
@foreach (var t in _templates)
{
<option value="@t.Id">@t.Name</option>
}
</select>
</div>
<div class="mb-3">
<label class="form-label">Description</label>
<input type="text" class="form-control" @bind="_createDescription" />
</div>
@if (_formError != null)
{
<div class="text-danger small mt-2">@_formError</div>
}
<div class="btn-group mt-3" role="group" aria-label="Create template actions">
<button class="btn btn-success" @onclick="CreateTemplate">Create</button>
<button class="btn btn-outline-secondary" @onclick="GoBack">Cancel</button>
</div>
</div>
</div>
}
</div>
@code {
[SupplyParameterFromQuery] public int? FolderId { get; set; }
[SupplyParameterFromQuery] public int? ParentId { get; set; }
private List<Template> _templates = new();
private bool _loading = true;
private string _createName = string.Empty;
private int _createParentId;
private string? _createDescription;
private string? _formError;
protected override async Task OnInitializedAsync()
{
try
{
_templates = (await TemplateEngineRepository.GetTemplateStubsAsync()).ToShellTemplates();
if (ParentId is int pid && _templates.Any(t => t.Id == pid))
{
_createParentId = pid;
}
}
catch (Exception ex)
{
_formError = $"Failed to load templates: {ex.Message}";
}
_loading = false;
}
private async Task CreateTemplate()
{
_formError = null;
if (string.IsNullOrWhiteSpace(_createName)) { _formError = "Name is required."; return; }
try
{
var user = await GetCurrentUserAsync();
var result = await TemplateService.CreateTemplateAsync(
_createName.Trim(), _createDescription?.Trim(),
_createParentId == 0 ? null : _createParentId, user,
folderId: FolderId);
if (result.IsSuccess)
{
NavigationManager.NavigateTo($"/design/templates/{result.Value.Id}");
}
else
{
_formError = result.Error;
}
}
catch (Exception ex)
{
_formError = ex.Message;
}
}
private void GoBack()
{
NavigationManager.NavigateTo("/design/templates");
}
// CentralUI-024: delegates to the shared helper so the claim type stays
// resolved through JwtTokenService rather than a duplicated magic string.
private Task<string> GetCurrentUserAsync()
=> AuthStateProvider.RequireRoleAsync(ZB.MOM.WW.ScadaBridge.Security.Roles.Designer);
}