Add EventOccurrenceParserService and update service registrations
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.
This commit is contained in:
@@ -0,0 +1,247 @@
|
||||
@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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user