mirror of https://github.com/ErsatzTV/ErsatzTV.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
135 lines
6.4 KiB
135 lines
6.4 KiB
@page "/schedules/{Id:int}" |
|
@page "/schedules/add" |
|
@using ErsatzTV.Application.ProgramSchedules |
|
@using ErsatzTV.Core.Scheduling |
|
@implements IDisposable |
|
@inject NavigationManager NavigationManager |
|
@inject ILogger<ScheduleEditor> Logger |
|
@inject ISnackbar Snackbar |
|
@inject IMediator Mediator |
|
|
|
<MudForm @ref="_form" @bind-IsValid="@_success" Style="max-height: 100%"> |
|
<MudPaper Square="true" Style="display: flex; height: 64px; min-height: 64px; width: 100%; z-index: 100; align-items: center"> |
|
<MudButton Variant="Variant.Filled" Color="Color.Primary" Class="ml-8" OnClick="HandleSubmitAsync" StartIcon="@(IsEdit ? Icons.Material.Filled.Save : Icons.Material.Filled.Add)">@(IsEdit ? "Save Schedule" : "Add Schedule")</MudButton> |
|
</MudPaper> |
|
<div class="d-flex flex-column" style="height: 100vh; overflow-x: auto"> |
|
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8"> |
|
<MudText Typo="Typo.h5" Class="mb-2">Schedule</MudText> |
|
<MudDivider Class="mb-6"/> |
|
<MudStack Row="true" Breakpoint="Breakpoint.SmAndDown" Class="form-field-stack gap-md-8 mb-5"> |
|
<div class="d-flex"> |
|
<MudText>Name</MudText> |
|
</div> |
|
<MudTextField @bind-Value="_model.Name" For="@(() => _model.Name)" Required="true" RequiredError="Schedule name is required!"/> |
|
</MudStack> |
|
<MudStack Row="true" Breakpoint="Breakpoint.SmAndDown" Class="form-field-stack gap-md-8 mb-5"> |
|
<div class="d-flex"> |
|
<MudText>Keep Multi-Part Episodes Together</MudText> |
|
</div> |
|
<MudCheckBox @bind-Value="@_model.KeepMultiPartEpisodesTogether" For="@(() => _model.KeepMultiPartEpisodesTogether)" Dense="true"> |
|
<MudText Typo="Typo.caption" Style="font-weight: normal">Group multi-part episodes when shuffling</MudText> |
|
</MudCheckBox> |
|
</MudStack> |
|
<MudStack Row="true" Breakpoint="Breakpoint.SmAndDown" Class="form-field-stack gap-md-8 mb-5"> |
|
<div class="d-flex"> |
|
<MudText>Treat Collections As Shows</MudText> |
|
</div> |
|
<MudCheckBox @bind-Value="@_model.TreatCollectionsAsShows" |
|
Disabled="@(_model.KeepMultiPartEpisodesTogether == false)" |
|
For="@(() => _model.TreatCollectionsAsShows)" Dense="true"> |
|
<MudText Typo="Typo.caption" Style="font-weight: normal">This is useful for multi-part crossover episodes</MudText> |
|
</MudCheckBox> |
|
</MudStack> |
|
<MudStack Row="true" Breakpoint="Breakpoint.SmAndDown" Class="form-field-stack gap-md-8 mb-5"> |
|
<div class="d-flex"> |
|
<MudText>Shuffle Schedule Items</MudText> |
|
</div> |
|
<MudCheckBox @bind-Value="@_model.ShuffleScheduleItems" For="@(() => _model.ShuffleScheduleItems)" Dense="true"> |
|
<MudText Typo="Typo.caption" Style="font-weight: normal">Note: this disables fixed start times and flood mode</MudText> |
|
</MudCheckBox> |
|
</MudStack> |
|
<MudStack Row="true" Breakpoint="Breakpoint.SmAndDown" Class="form-field-stack gap-md-8 mb-5"> |
|
<div class="d-flex"> |
|
<MudText>Random Start Point</MudText> |
|
</div> |
|
<MudCheckBox @bind-Value="@_model.RandomStartPoint" For="@(() => _model.RandomStartPoint)" Dense="true"/> |
|
</MudStack> |
|
<MudStack Row="true" Breakpoint="Breakpoint.SmAndDown" Class="form-field-stack gap-md-8 mb-5"> |
|
<div class="d-flex"> |
|
<MudText>Fixed Start Time Behavior</MudText> |
|
</div> |
|
<MudSelect @bind-Value="@_model.FixedStartTimeBehavior" For="@(() => _model.FixedStartTimeBehavior)"> |
|
<MudSelectItem Value="FixedStartTimeBehavior.Strict">Strict - Wait For Exact Start Time</MudSelectItem> |
|
<MudSelectItem Value="FixedStartTimeBehavior.Flexible">Flexible - Start As Soon As Possible</MudSelectItem> |
|
</MudSelect> |
|
</MudStack> |
|
</MudContainer> |
|
</div> |
|
</MudForm> |
|
|
|
@code { |
|
private readonly CancellationTokenSource _cts = new(); |
|
|
|
[Parameter] |
|
public int Id { get; set; } |
|
|
|
private readonly ProgramScheduleEditViewModel _model = new(); |
|
private MudForm _form; |
|
private bool _success; |
|
|
|
public void Dispose() |
|
{ |
|
_cts.Cancel(); |
|
_cts.Dispose(); |
|
} |
|
|
|
protected override async Task OnParametersSetAsync() |
|
{ |
|
if (IsEdit) |
|
{ |
|
Option<ProgramScheduleViewModel> maybeProgramSchedule = await Mediator.Send(new GetProgramScheduleById(Id), _cts.Token); |
|
maybeProgramSchedule.Match( |
|
viewModel => |
|
{ |
|
_model.Id = viewModel.Id; |
|
_model.Name = viewModel.Name; |
|
_model.ShuffleScheduleItems = viewModel.ShuffleScheduleItems; |
|
_model.KeepMultiPartEpisodesTogether = viewModel.KeepMultiPartEpisodesTogether; |
|
_model.TreatCollectionsAsShows = viewModel.TreatCollectionsAsShows; |
|
_model.RandomStartPoint = viewModel.RandomStartPoint; |
|
_model.FixedStartTimeBehavior = viewModel.FixedStartTimeBehavior; |
|
}, |
|
() => NavigationManager.NavigateTo("404")); |
|
} |
|
else |
|
{ |
|
_model.Name = "New Schedule"; |
|
} |
|
} |
|
|
|
private bool IsEdit => Id > 0; |
|
|
|
private async Task HandleSubmitAsync() |
|
{ |
|
await _form.Validate(); |
|
if (_success) |
|
{ |
|
Either<BaseError, EntityIdResult> result = IsEdit |
|
? await Mediator.Send(_model.ToUpdate(), _cts.Token).MapT(r => r as EntityIdResult) |
|
: await Mediator.Send(_model.ToCreate(), _cts.Token).MapT(r => r as EntityIdResult); |
|
|
|
result.Match( |
|
programSchedule => |
|
{ |
|
string destination = IsEdit ? "/schedules" : $"/schedules/{programSchedule.Id}/items"; |
|
NavigationManager.NavigateTo(destination); |
|
}, |
|
error => |
|
{ |
|
Snackbar.Add(error.Value, Severity.Error); |
|
Logger.LogError("Unexpected error saving schedule: {Error}", error.Value); |
|
}); |
|
} |
|
} |
|
|
|
} |