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 DataPageBase : ComponentBase, IDisposable { protected DataPageState state; protected IEnumerable data; protected string syncButtonText = "..."; protected string parseButtonText = "..."; private readonly List campaignTypes = []; protected abstract Campaign.CampaignType? SyncCampaignType { get; } protected abstract Campaign.CampaignType? ParseCampaignType { 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 void OnInitialized() { campaignTypes.Clear(); if (SyncCampaignType.HasValue) { campaignTypes.Add(SyncCampaignType.Value); } if (ParseCampaignType.HasValue) { campaignTypes.Add(ParseCampaignType.Value); } } protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { ChangeState(DataPageState.Init); var finalState = DataPageState.Idle; var state = await AuthenticationStateProvider.GetAuthenticationStateAsync(); if (HasPermission(state.User)) { var operationInProgress = await HeadquartersService.HasActiveCampaignsAsync(campaignTypes); if (operationInProgress) { finalState = DataPageState.DataWaiting; } 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> GetDataAsync(); protected async Task SyncDataAsync() { if (state == DataPageState.DataWaiting) return; ChangeState(DataPageState.DataWaiting); if (await HeadquartersService.HasActiveCampaignsAsync(campaignTypes)) { ChangeState(DataPageState.DataWaiting); } else { // TODO: Use user id var campaign = await HeadquartersService.InitiateCampaignAsync(SyncCampaignType!.Value, ""); CampaignManagementState.EnqueueCampaign(campaign); } } protected async Task ParseDataAsync() { if (state == DataPageState.DataWaiting) return; if (await HeadquartersService.HasActiveCampaignsAsync(campaignTypes)) { ChangeState(DataPageState.DataWaiting); } else { var dialogResult = await DialogService.OpenAsync( "Отправка файла", new Dictionary() { // TODO: Use user id { nameof(StartParsing.UploaderId), "" } }, new DialogOptions() { Width = "600px", CloseDialogOnEsc = false, CloseDialogOnOverlayClick = false, ShowClose = false }); if (dialogResult != null) { ChangeState(DataPageState.DataWaiting); // TODO: Use user id var campaign = await HeadquartersService.InitiateCampaignAsync(ParseCampaignType!.Value, "", new CampaignParseArgs() { fileToParseId = (int)dialogResult }); CampaignManagementState.EnqueueCampaign(campaign); } } } private void ChangeState(DataPageState state) { if (this.state == state) return; this.state = state; SetButtonsText(); StateHasChanged(); } private void SetButtonsText() { switch (state) { case DataPageState.Init: syncButtonText = "..."; parseButtonText = "..."; break; case DataPageState.Loading: case DataPageState.Idle: syncButtonText = "Синхронизировать"; parseButtonText = "Спарсить"; break; case DataPageState.DataWaiting: syncButtonText = "Идет синхронизация..."; parseButtonText = "Идет парсинг..."; break; } } private void OnCampaignCreated(Campaign campaign) { if (campaignTypes.Contains(campaign.Type)) { InvokeAsync(() => ChangeState(DataPageState.DataWaiting)); } } private void OnCampaignEnded(int campaignId, Campaign.CampaignType type, DateTime endedAt, string failureReason) { if (campaignTypes.Contains(type)) { Task.Run(RefreshData); } } private async Task RefreshData() { await InvokeAsync(() => ChangeState(DataPageState.Loading)); var refreshedData = await GetDataAsync(); await InvokeAsync(() => { data = refreshedData; ChangeState(DataPageState.Idle); }); } } }