cd34be1f82
Registered the new EventOccurrenceParserService in Program.cs to handle event occurrence parsing. Updated the _Imports.razor file to reflect the renaming of the EventCalendar component to Calendar. Removed the obsolete EventCalendar component to streamline the codebase.
248 lines
9.1 KiB
Plaintext
248 lines
9.1 KiB
Plaintext
@page "/calendar/event-occurrences/import"
|
|
@attribute [Authorize]
|
|
@using Core.Entities
|
|
@using Core.Models
|
|
@using Core.Services
|
|
@using Microsoft.EntityFrameworkCore
|
|
@using WebApp.Components.Shared.Components
|
|
@using MudBlazor
|
|
@inject IEventOccurrenceParserService ParserService
|
|
@inject AppDbContext Context
|
|
@inject NavigationManager NavigationManager
|
|
@inject ISnackbar Snackbar
|
|
|
|
<PageHeader
|
|
Title="Import Event Occurrences"
|
|
Description="Parse and import event occurrence data from text"
|
|
ShowBackButton="true"
|
|
BackButtonUrl="/calendar/event-occurrences" />
|
|
|
|
<MudGrid>
|
|
<MudItem xs="12" md="6">
|
|
<MudPaper Elevation="2" Class="pa-6">
|
|
<MudText Typo="Typo.h5" Class="mb-4">Paste Event Occurrence Data</MudText>
|
|
<MudStack Spacing="3">
|
|
<MudTextField
|
|
T="string"
|
|
Label="Event Occurrence Text"
|
|
@bind-Value="_inputText"
|
|
Variant="Variant.Outlined"
|
|
Lines="15"
|
|
MultiLine="true"
|
|
Placeholder="Paste event occurrence text here..."
|
|
HelperText="Paste the event schedule text in the format expected by the parser" />
|
|
|
|
<MudStack Row="true" Spacing="2">
|
|
<MudButton
|
|
Variant="Variant.Filled"
|
|
Color="Color.Primary"
|
|
StartIcon="@Icons.Material.Filled.Article"
|
|
OnClick="HandleParse"
|
|
Disabled="@_isParsing">
|
|
Parse
|
|
</MudButton>
|
|
<MudButton
|
|
Variant="Variant.Text"
|
|
OnClick="HandleClear"
|
|
Disabled="@_isParsing">
|
|
Clear
|
|
</MudButton>
|
|
</MudStack>
|
|
</MudStack>
|
|
</MudPaper>
|
|
</MudItem>
|
|
|
|
<MudItem xs="12" md="6">
|
|
<MudPaper Elevation="2" Class="pa-6">
|
|
<MudText Typo="Typo.h5" Class="mb-4">Parsed Results</MudText>
|
|
|
|
@if (_isParsing)
|
|
{
|
|
<MudProgressLinear Indeterminate="true" Class="mb-4" />
|
|
<MudText>Parsing...</MudText>
|
|
}
|
|
else if (_parseResult == null)
|
|
{
|
|
<MudText Class="mud-text-secondary">Parse text to see results here</MudText>
|
|
}
|
|
else
|
|
{
|
|
<MudStack Spacing="3">
|
|
@* Errors *@
|
|
@if (_parseResult.Errors.Any())
|
|
{
|
|
@foreach (var error in _parseResult.Errors)
|
|
{
|
|
<MudAlert Severity="Severity.Error" Dense="true">@error</MudAlert>
|
|
}
|
|
}
|
|
|
|
@* Warnings *@
|
|
@if (_parseResult.Warnings.Any())
|
|
{
|
|
@foreach (var warning in _parseResult.Warnings)
|
|
{
|
|
<MudAlert Severity="Severity.Warning" Dense="true">@warning</MudAlert>
|
|
}
|
|
}
|
|
|
|
@* Summary *@
|
|
@if (_parseResult.IsSuccess && _parseResult.TotalParsed > 0)
|
|
{
|
|
<MudAlert Severity="Severity.Success" Dense="true">
|
|
Successfully parsed @_parseResult.TotalParsed occurrence(s) from @_parseResult.Occurrences.Count event definition(s)
|
|
</MudAlert>
|
|
}
|
|
|
|
@* Parsed Occurrences List *@
|
|
@if (_parseResult.IsSuccess && _parseResult.Occurrences.Any())
|
|
{
|
|
<MudText Typo="Typo.h6" Class="mt-4 mb-2">Occurrences by Event:</MudText>
|
|
<MudExpansionPanels Elevation="0">
|
|
@foreach (var kvp in _parseResult.Occurrences.OrderBy(x => GetEventName(x.Key)))
|
|
{
|
|
<MudExpansionPanel Text="@GetEventName(kvp.Key)">
|
|
<MudTable Items="@kvp.Value" Dense="true" Hover="true" Striped="true">
|
|
<HeaderContent>
|
|
<MudTh>Name</MudTh>
|
|
<MudTh>Date</MudTh>
|
|
<MudTh>Time</MudTh>
|
|
<MudTh>Location</MudTh>
|
|
</HeaderContent>
|
|
<RowTemplate>
|
|
<MudTd DataLabel="Name">@context.Name</MudTd>
|
|
<MudTd DataLabel="Date">@context.Date</MudTd>
|
|
<MudTd DataLabel="Time">@context.Time</MudTd>
|
|
<MudTd DataLabel="Location">@(context.Location ?? "-")</MudTd>
|
|
</RowTemplate>
|
|
</MudTable>
|
|
</MudExpansionPanel>
|
|
}
|
|
</MudExpansionPanels>
|
|
|
|
<MudStack Row="true" Spacing="2" Class="mt-4">
|
|
<MudButton
|
|
Variant="Variant.Filled"
|
|
Color="Color.Success"
|
|
StartIcon="@Icons.Material.Filled.Save"
|
|
OnClick="HandleSaveToDatabase"
|
|
Disabled="@_isSaving">
|
|
Save to Database
|
|
</MudButton>
|
|
<MudButton
|
|
Variant="Variant.Text"
|
|
OnClick="HandleClearResults">
|
|
Clear Results
|
|
</MudButton>
|
|
</MudStack>
|
|
}
|
|
else if (_parseResult.IsSuccess && _parseResult.TotalParsed == 0)
|
|
{
|
|
<MudAlert Severity="Severity.Info" Dense="true">
|
|
No occurrences were parsed from the text. Please check the format.
|
|
</MudAlert>
|
|
}
|
|
</MudStack>
|
|
}
|
|
</MudPaper>
|
|
</MudItem>
|
|
</MudGrid>
|
|
|
|
@code {
|
|
private string _inputText = string.Empty;
|
|
private EventOccurrenceParseResult? _parseResult;
|
|
private bool _isParsing = false;
|
|
private bool _isSaving = false;
|
|
|
|
private async Task HandleParse()
|
|
{
|
|
if (string.IsNullOrWhiteSpace(_inputText))
|
|
{
|
|
Snackbar.Add("Please enter text to parse", Severity.Warning);
|
|
return;
|
|
}
|
|
|
|
_isParsing = true;
|
|
try
|
|
{
|
|
// Get EventDefinitions from database
|
|
var events = await Context.Events.ToListAsync();
|
|
|
|
// Parse the text
|
|
_parseResult = ParserService.ParseFromText(_inputText, events);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Snackbar.Add($"Error parsing text: {ex.Message}", Severity.Error);
|
|
_parseResult = new EventOccurrenceParseResult
|
|
{
|
|
Errors = { $"Error: {ex.Message}" }
|
|
};
|
|
}
|
|
finally
|
|
{
|
|
_isParsing = false;
|
|
}
|
|
}
|
|
|
|
private void HandleClear()
|
|
{
|
|
_inputText = string.Empty;
|
|
_parseResult = null;
|
|
}
|
|
|
|
private void HandleClearResults()
|
|
{
|
|
_parseResult = null;
|
|
}
|
|
|
|
private async Task HandleSaveToDatabase()
|
|
{
|
|
if (_parseResult == null || !_parseResult.IsSuccess || _parseResult.TotalParsed == 0)
|
|
{
|
|
Snackbar.Add("No valid parsed occurrences to save", Severity.Warning);
|
|
return;
|
|
}
|
|
|
|
_isSaving = true;
|
|
try
|
|
{
|
|
var savedCount = 0;
|
|
foreach (var kvp in _parseResult.Occurrences)
|
|
{
|
|
foreach (var occurrence in kvp.Value)
|
|
{
|
|
// Add each occurrence to the database
|
|
await Context.EventOccurrences.AddAsync(occurrence);
|
|
savedCount++;
|
|
}
|
|
}
|
|
|
|
await Context.SaveChangesAsync();
|
|
Snackbar.Add($"Successfully saved {savedCount} occurrence(s) to database", Severity.Success);
|
|
|
|
// Navigate back to the calendar index after a short delay
|
|
await Task.Delay(1000);
|
|
NavigationManager.NavigateTo("/calendar/event-occurrences");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Snackbar.Add($"Error saving to database: {ex.Message}", Severity.Error);
|
|
}
|
|
finally
|
|
{
|
|
_isSaving = false;
|
|
}
|
|
}
|
|
|
|
private string GetEventName(EventDefinition eventDefinition)
|
|
{
|
|
if (eventDefinition == EventDefinition.GeneralSchedule)
|
|
return "General Schedule";
|
|
if (eventDefinition == EventDefinition.VotingDelegates)
|
|
return "Voting Delegates";
|
|
return eventDefinition.Name;
|
|
}
|
|
}
|
|
|