Files
hcs/Hcs.WebApp/Components/Shared/SyncedPageBase.cs

191 lines
6.1 KiB
C#

using Hcs.WebApp.BackgroundServices;
using Hcs.WebApp.Components.Dialogs;
using Hcs.WebApp.Data.Hcs;
using Hcs.WebApp.Data.Hcs.CampaignArgs;
using Hcs.WebApp.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization;
using Radzen;
using System.Security.Claims;
namespace Hcs.WebApp.Components.Shared
{
public abstract class SyncedPageBase<TData> : ComponentBase, IDisposable
{
protected SyncedPageState state;
protected IEnumerable<TData> data;
protected string syncButtonText = "...";
protected string parseButtonText = "...";
protected abstract Campaign.CampaignType CampaignType { get; }
[Inject]
private AuthenticationStateProvider AuthenticationStateProvider { get; set; }
[Inject]
private HeadquartersService HeadquartersService { get; set; }
[Inject]
private CampaignManagementState CampaignManagementState { get; set; }
[Inject]
protected DialogService DialogService { get; set; }
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
ChangeState(SyncedPageState.Init);
var finalState = SyncedPageState.Idle;
var state = await AuthenticationStateProvider.GetAuthenticationStateAsync();
if (HasPermission(state.User))
{
var operationInProgress = await HeadquartersService.HasActiveCampaignAsync(CampaignType);
if (operationInProgress)
{
finalState = SyncedPageState.SyncWaiting;
}
CampaignManagementState.OnCampaignCreated += OnCampaignCreated;
CampaignManagementState.OnCampaignEnded += OnCampaignEnded;
data = await GetDataAsync();
}
ChangeState(finalState);
}
}
public void Dispose()
{
CampaignManagementState.OnCampaignCreated -= OnCampaignCreated;
CampaignManagementState.OnCampaignEnded -= OnCampaignEnded;
}
protected abstract bool HasPermission(ClaimsPrincipal user);
protected abstract Task<IEnumerable<TData>> GetDataAsync();
protected async Task SyncDataAsync()
{
if (state == SyncedPageState.SyncWaiting) return;
ChangeState(SyncedPageState.SyncWaiting);
if (await HeadquartersService.HasActiveCampaignAsync(CampaignType))
{
ChangeState(SyncedPageState.SyncWaiting);
}
else
{
// TODO: Use user id
var campaign = await HeadquartersService.InitiateCampaignAsync(CampaignType, "");
CampaignManagementState.EnqueueCampaign(campaign);
}
}
protected async Task ParseDataAsync()
{
if (state == SyncedPageState.SyncWaiting) return;
if (await HeadquartersService.HasActiveCampaignAsync(CampaignType))
{
ChangeState(SyncedPageState.SyncWaiting);
}
else
{
var dialogResult = await DialogService.OpenAsync<StartParsing>(
"Отправка файла",
new Dictionary<string, object>()
{
// TODO: Use user id
{ nameof(StartParsing.UploaderId), "" }
},
new DialogOptions()
{
Width = "600px",
CloseDialogOnEsc = false,
CloseDialogOnOverlayClick = false,
ShowClose = false
});
var fileToParseId = -1;
if (dialogResult != null && int.TryParse(dialogResult, out fileToParseId))
{
ChangeState(SyncedPageState.SyncWaiting);
// TODO: Use user id
var campaign = await HeadquartersService.InitiateCampaignAsync(CampaignType, "", new CampaignParseArgs()
{
FileToParseId = fileToParseId
});
CampaignManagementState.EnqueueCampaign(campaign);
}
}
}
private void ChangeState(SyncedPageState state)
{
if (this.state == state) return;
this.state = state;
SetButtonsText();
StateHasChanged();
}
private void SetButtonsText()
{
switch (state)
{
case SyncedPageState.Init:
syncButtonText = "...";
parseButtonText = "...";
break;
case SyncedPageState.Loading:
case SyncedPageState.Idle:
syncButtonText = "Синхронизировать";
parseButtonText = "Спарсить";
break;
case SyncedPageState.SyncWaiting:
syncButtonText = "Идет синхронизация...";
parseButtonText = "Идет парсинг...";
break;
}
}
private void OnCampaignCreated(Campaign campaign)
{
if (campaign.Type == CampaignType)
{
InvokeAsync(() => ChangeState(SyncedPageState.SyncWaiting));
}
}
private void OnCampaignEnded(int campaignId, Campaign.CampaignType type, DateTime endedAt, string failureReason)
{
if (type == CampaignType)
{
Task.Run(RefreshData);
}
}
private async Task RefreshData()
{
await InvokeAsync(() => ChangeState(SyncedPageState.Loading));
var refreshedData = await GetDataAsync();
await InvokeAsync(() =>
{
data = refreshedData;
ChangeState(SyncedPageState.Idle);
});
}
}
}