From 9101d1bf4c51241908321eb21bce4a19763d5739 Mon Sep 17 00:00:00 2001 From: "HOME-LAPTOP\\kshkulev" Date: Wed, 5 Nov 2025 10:38:15 +0900 Subject: [PATCH] Add campaigns page --- Hcs.WebApp/Components/Layout/MainLayout.razor | 2 + Hcs.WebApp/Components/Pages/Campaigns.razor | 131 ++++++++++++++++++ .../Components/Pages/Registry/Common.razor | 2 +- Hcs.WebApp/Data/Hcs/Campaign.cs | 2 +- Hcs.WebApp/Services/HeadquartersService.cs | 6 + 5 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 Hcs.WebApp/Components/Pages/Campaigns.razor diff --git a/Hcs.WebApp/Components/Layout/MainLayout.razor b/Hcs.WebApp/Components/Layout/MainLayout.razor index 3a84a37..8da0ffa 100644 --- a/Hcs.WebApp/Components/Layout/MainLayout.razor +++ b/Hcs.WebApp/Components/Layout/MainLayout.razor @@ -28,6 +28,8 @@ + + diff --git a/Hcs.WebApp/Components/Pages/Campaigns.razor b/Hcs.WebApp/Components/Pages/Campaigns.razor new file mode 100644 index 0000000..9bd1a99 --- /dev/null +++ b/Hcs.WebApp/Components/Pages/Campaigns.razor @@ -0,0 +1,131 @@ +@page "/campaigns" + +@using Hcs.WebApp.BackgroundServices +@using Hcs.WebApp.Services +@using Microsoft.AspNetCore.Authorization + +@implements IDisposable + +@attribute [Authorize] + +@inject AuthenticationStateProvider AuthenticationStateProvider +@inject HeadquartersService HeadquartersService +@inject CampaignManagementState CampaignManagementState + +Кампании + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@code { + enum CampaignsPageState + { + Init, + Loading, + Idle + } + + CampaignsPageState state; + IEnumerable campaigns; + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + await base.OnAfterRenderAsync(firstRender); + + if (firstRender) + { + ChangeState(CampaignsPageState.Loading); + + var state = await AuthenticationStateProvider.GetAuthenticationStateAsync(); + if (state.User.IsInRole(AppRole.ADMINISTRATOR_TYPE) || state.User.IsInRole(AppRole.OPERATOR_TYPE)) + { + CampaignManagementState.OnCampaignCreated += OnCampaignCreated; + CampaignManagementState.OnCampaignEnded += OnCampaignEnded; + + campaigns = await HeadquartersService.GetCampaignsAsync(); + } + + ChangeState(CampaignsPageState.Idle); + } + } + + async Task RowExpandAsync(Campaign campaign) + { + // TODO + } + + void ChangeState(CampaignsPageState state) + { + if (this.state == state) return; + + this.state = state; + + StateHasChanged(); + } + + void OnCampaignCreated(Campaign campaign) + { + Task.Run(RefreshCampaigns); + } + + void OnCampaignEnded(Campaign campaign) + { + Task.Run(RefreshCampaigns); + } + + async Task RefreshCampaigns() + { + await InvokeAsync(() => ChangeState(CampaignsPageState.Loading)); + + var refreshedCampaigns = await HeadquartersService.GetCampaignsAsync(); + + await InvokeAsync(() => + { + campaigns = refreshedCampaigns; + + ChangeState(CampaignsPageState.Idle); + }); + } + + public void Dispose() + { + CampaignManagementState.OnCampaignCreated -= OnCampaignCreated; + CampaignManagementState.OnCampaignEnded -= OnCampaignEnded; + } +} diff --git a/Hcs.WebApp/Components/Pages/Registry/Common.razor b/Hcs.WebApp/Components/Pages/Registry/Common.razor index 4b466f6..7ebfb27 100644 --- a/Hcs.WebApp/Components/Pages/Registry/Common.razor +++ b/Hcs.WebApp/Components/Pages/Registry/Common.razor @@ -72,8 +72,8 @@ OperationWaiting } - IEnumerable registries; CommonPageState state; + IEnumerable registries; string syncText = "..."; bool hasError; string errorMessage; diff --git a/Hcs.WebApp/Data/Hcs/Campaign.cs b/Hcs.WebApp/Data/Hcs/Campaign.cs index 6d44110..c152a6b 100644 --- a/Hcs.WebApp/Data/Hcs/Campaign.cs +++ b/Hcs.WebApp/Data/Hcs/Campaign.cs @@ -26,7 +26,7 @@ namespace Hcs.WebApp.Data.Hcs public string? FailureReason { get; set; } - public virtual ICollection Operations { get; set; } = []; + public virtual ICollection? Operations { get; set; } = null; [NotMapped] public bool Completed => EndedAt.HasValue; diff --git a/Hcs.WebApp/Services/HeadquartersService.cs b/Hcs.WebApp/Services/HeadquartersService.cs index 741f401..cc04fed 100644 --- a/Hcs.WebApp/Services/HeadquartersService.cs +++ b/Hcs.WebApp/Services/HeadquartersService.cs @@ -11,6 +11,12 @@ namespace Hcs.WebApp.Services return await context.Campaigns.AnyAsync(x => x.Type == type && !x.EndedAt.HasValue); } + public async Task> GetCampaignsAsync() + { + using var context = GetNewContext(); + return await context.Campaigns.ToListAsync(); + } + public async Task> GetNotEndedCampaignsAsync() { using var context = GetNewContext();