Files
hcs/Hcs.WebApp/Components/Pages/Campaigns.razor

288 lines
12 KiB
Plaintext

@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
@inject EventsAggregator EventsAggregator
<PageTitle>Кампании</PageTitle>
<AuthorizedContent Roles="@($"{AppRole.ADMINISTRATOR_TYPE},{AppRole.OPERATOR_TYPE}")">
<Content>
<RadzenStack>
<RadzenRow AlignItems="AlignItems.Center">
<RadzenColumn Size="12" SizeMD="12">
<RadzenText Text="Кампании" TextStyle="TextStyle.H5" class="rz-m-0" />
</RadzenColumn>
</RadzenRow>
<RadzenRow>
<RadzenColumn SizeMD="12">
<div>
<RadzenDataGrid @ref="@campaignsDataGrid" TItem="Campaign" Data="@campaigns" RowExpand="@RowExpandAsync" RowCollapse="@RowCollapse" IsLoading="@(state != PageState.Idle)" CellRender="@OnCellRender" AllowFiltering="true" AllowPaging="true" ShowPagingSummary="true" PageSizeOptions=@(new int[] { 5, 10, 20, 30 }) AllowSorting="true" AllowColumnResize="true" ExpandMode="DataGridExpandMode.Single">
<Template Context="campaign">
<RadzenDataGrid @ref="@operationsDataGrid" Data="@campaign.Operations" CellRender="@OnCellRender" AllowFiltering="true" AllowPaging="true" ShowPagingSummary="true" PageSizeOptions=@(new int[] { 5, 10, 20, 30 }) AllowSorting="true" AllowColumnResize="true">
<Columns>
<RadzenDataGridColumn Property="@nameof(Operation.Id)" Title="ID" SortOrder="SortOrder.Descending" Resizable="false" Width="100px" MaxWidth="100px" />
<RadzenDataGridColumn Property="@nameof(Operation.Type)" Title="Тип операции" />
<RadzenDataGridColumn Property="@nameof(Operation.CreatedAt)" Title="Дата создания" Resizable="false" Width="150px" MaxWidth="150px" />
<RadzenDataGridColumn Property="@nameof(Operation.StartedAt)" Title="Дата начала" Resizable="false" Width="150px" MaxWidth="150px" />
<RadzenDataGridColumn Property="@nameof(Operation.EndedAt)" Title="Дата окончания" Resizable="false" Width="150px" MaxWidth="150px" />
<RadzenDataGridColumn Property="@nameof(Operation.MessageGuid)" Title="ID сообщения" />
<RadzenDataGridColumn Property="@nameof(Operation.FailureReason)" Title="Причина ошибки" />
</Columns>
</RadzenDataGrid>
</Template>
<Columns>
<RadzenDataGridColumn TItem="Campaign" Property="@nameof(Campaign.Id)" Title="ID" SortOrder="SortOrder.Descending" Resizable="false" Width="100px" MaxWidth="100px" />
<RadzenDataGridColumn TItem="Campaign" Property="@nameof(Campaign.Type)" Title="Тип кампании" />
<RadzenDataGridColumn Title="Прогресс" Filterable="false" Sortable="false" Resizable="false" Width="70px" MaxWidth="70px">
<Template Context="campaign">
<RadzenProgressBar ProgressBarStyle="@(campaign.EndedAt.HasValue ? (string.IsNullOrEmpty(campaign.FailureReason) ? ProgressBarStyle.Success : ProgressBarStyle.Danger) : ProgressBarStyle.Primary)" Value="@campaign.Progress" ShowValue="false" />
</Template>
</RadzenDataGridColumn>
<RadzenDataGridColumn TItem="Campaign" Property="@nameof(Campaign.CreatedAt)" Title="Дата создания" Resizable="false" Width="150px" MaxWidth="150px" />
<RadzenDataGridColumn TItem="Campaign" Property="@nameof(Campaign.StartedAt)" Title="Дата начала" Resizable="false" Width="150px" MaxWidth="150px" />
<RadzenDataGridColumn TItem="Campaign" Property="@nameof(Campaign.EndedAt)" Title="Дата окончания" Resizable="false" Width="150px" MaxWidth="150px" />
<RadzenDataGridColumn TItem="Campaign" Property="@nameof(Campaign.FailureReason)" Title="Причина ошибки" />
</Columns>
</RadzenDataGrid>
</div>
</RadzenColumn>
</RadzenRow>
</RadzenStack>
</Content>
</AuthorizedContent>
@code {
PageState state;
RadzenDataGrid<Campaign> campaignsDataGrid;
RadzenDataGrid<Operation> operationsDataGrid;
IEnumerable<Campaign>? campaigns;
Campaign? expandedCampaign;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
await base.OnAfterRenderAsync(firstRender);
if (firstRender)
{
ChangeState(PageState.Loading);
var state = await AuthenticationStateProvider.GetAuthenticationStateAsync();
if (state.User.IsOperatorOrHigher())
{
campaigns = await HeadquartersService.GetCampaignsAsync();
CampaignManagementState.OnCampaignCreated += OnCampaignCreated;
CampaignManagementState.OnCampaignStarted += OnCampaignStarted;
CampaignManagementState.OnCampaignProgressStep += OnCampaignProgressStep;
CampaignManagementState.OnCampaignEnded += OnCampaignEnded;
EventsAggregator.OnOperationStarted += OnOperationStarted;
EventsAggregator.OnOperationExecuted += OnOperationExecuted;
EventsAggregator.OnOperationEnded += OnOperationEnded;
}
ChangeState(PageState.Idle);
}
}
async Task RowExpandAsync(Campaign campaign)
{
expandedCampaign = campaign;
if (campaign.Operations == null)
{
campaign.Operations = await HeadquartersService.GetOperationsAsync(campaign.Id);
}
}
void RowCollapse(Campaign campaign)
{
if (expandedCampaign != null && expandedCampaign.Id == campaign.Id)
{
expandedCampaign = null;
}
campaign.Operations = null;
}
void OnCellRender(DataGridCellRenderEventArgs<Campaign> args)
{
if (args.Column.Property == nameof(Campaign.FailureReason))
{
args.Attributes.Add("class", "white-text");
args.Attributes.Add("style", $"background-color: {(!string.IsNullOrEmpty(args.Data.FailureReason) ? "var(--rz-danger)" : "var(--rz-base-background-color)")};");
}
}
void OnCellRender(DataGridCellRenderEventArgs<Operation> args)
{
if (args.Column.Property == nameof(Operation.FailureReason))
{
args.Attributes.Add("class", "white-text");
args.Attributes.Add("style", $"background-color: {(!string.IsNullOrEmpty(args.Data.FailureReason) ? "var(--rz-danger)" : "var(--rz-base-background-color)")};");
}
}
void ChangeState(PageState state)
{
if (this.state == state) return;
this.state = state;
StateHasChanged();
}
void OnCampaignCreated(Campaign campaign)
{
Task.Run(RefreshCampaigns);
}
async Task RefreshCampaigns()
{
await InvokeAsync(() => ChangeState(PageState.Loading));
var refreshedCampaigns = await HeadquartersService.GetCampaignsAsync();
await InvokeAsync(() =>
{
campaigns = refreshedCampaigns;
expandedCampaign = null;
ChangeState(PageState.Idle);
});
}
void OnCampaignStarted(int campaignId, DateTime startedAt)
{
InvokeAsync(() =>
{
var targetCampaign = campaigns?.FirstOrDefault(x => x.Id == campaignId);
if (targetCampaign != null)
{
targetCampaign.StartedAt = startedAt;
campaignsDataGrid.Reload();
}
if (expandedCampaign != null && expandedCampaign.Id == campaignId)
{
campaignsDataGrid.CollapseAll();
}
});
}
void OnCampaignProgressStep(int campaignId, int step, int progress)
{
InvokeAsync(() =>
{
var targetCampaign = campaigns?.FirstOrDefault(x => x.Id == campaignId);
if (targetCampaign != null)
{
targetCampaign.Step = step;
targetCampaign.Progress = progress;
campaignsDataGrid.Reload();
if (expandedCampaign != null && expandedCampaign.Id == campaignId)
{
campaignsDataGrid.CollapseAll();
}
}
});
}
void OnCampaignEnded(int campaignId, Campaign.CampaignType type, DateTime endedAt, string failureReason)
{
InvokeAsync(() =>
{
var targetCampaign = campaigns?.FirstOrDefault(x => x.Id == campaignId);
if (targetCampaign != null)
{
targetCampaign.EndedAt = endedAt;
targetCampaign.FailureReason = failureReason;
campaignsDataGrid.Reload();
}
if (expandedCampaign != null && expandedCampaign.Id == campaignId)
{
campaignsDataGrid.CollapseAll();
}
});
}
void OnOperationStarted(int operationId, int campaignId, DateTime startedAt)
{
InvokeAsync(() =>
{
if (expandedCampaign != null && expandedCampaign.Id == campaignId)
{
var targetOperation = expandedCampaign.Operations?.FirstOrDefault(x => x.Id == operationId);
if (targetOperation != null)
{
targetOperation.StartedAt = startedAt;
operationsDataGrid.Reload();
}
}
});
}
void OnOperationExecuted(int operationId, int campaignId, string messageGuid)
{
InvokeAsync(() =>
{
if (expandedCampaign != null && expandedCampaign.Id == campaignId)
{
var targetOperation = expandedCampaign.Operations?.FirstOrDefault(x => x.Id == operationId);
if (targetOperation != null)
{
targetOperation.MessageGuid = messageGuid;
operationsDataGrid.Reload();
}
}
});
}
void OnOperationEnded(int operationId, int campaignId, DateTime endedAt, string failureReason)
{
InvokeAsync(() =>
{
if (expandedCampaign != null && expandedCampaign.Id == campaignId)
{
var targetOperation = expandedCampaign.Operations?.FirstOrDefault(x => x.Id == operationId);
if (targetOperation != null)
{
targetOperation.EndedAt = endedAt;
targetOperation.FailureReason = failureReason;
operationsDataGrid.Reload();
}
}
});
}
public void Dispose()
{
CampaignManagementState.OnCampaignCreated -= OnCampaignCreated;
CampaignManagementState.OnCampaignStarted -= OnCampaignStarted;
CampaignManagementState.OnCampaignProgressStep -= OnCampaignProgressStep;
CampaignManagementState.OnCampaignEnded -= OnCampaignEnded;
EventsAggregator.OnOperationStarted -= OnOperationStarted;
EventsAggregator.OnOperationExecuted -= OnOperationExecuted;
EventsAggregator.OnOperationEnded -= OnOperationEnded;
}
}