|
|
|
@ -1,12 +1,16 @@ |
|
|
|
@page "/playouts" |
|
|
|
@page "/playouts" |
|
|
|
|
|
|
|
@using System.Globalization |
|
|
|
@using ErsatzTV.Application.Configuration |
|
|
|
@using ErsatzTV.Application.Configuration |
|
|
|
@using ErsatzTV.Application.Playouts |
|
|
|
@using ErsatzTV.Application.Playouts |
|
|
|
@using ErsatzTV.Core.Scheduling |
|
|
|
@using ErsatzTV.Core.Scheduling |
|
|
|
|
|
|
|
@using ErsatzTV.Core.Notifications |
|
|
|
|
|
|
|
@using MediatR.Courier |
|
|
|
@implements IDisposable |
|
|
|
@implements IDisposable |
|
|
|
@inject IDialogService Dialog |
|
|
|
@inject IDialogService Dialog |
|
|
|
@inject IMediator Mediator |
|
|
|
@inject IMediator Mediator |
|
|
|
@inject ChannelWriter<IBackgroundServiceRequest> WorkerChannel |
|
|
|
@inject ChannelWriter<IBackgroundServiceRequest> WorkerChannel |
|
|
|
@inject IEntityLocker EntityLocker; |
|
|
|
@inject IEntityLocker EntityLocker; |
|
|
|
|
|
|
|
@inject ICourier Courier; |
|
|
|
|
|
|
|
|
|
|
|
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8"> |
|
|
|
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8"> |
|
|
|
<div> |
|
|
|
<div> |
|
|
|
@ -50,7 +54,7 @@ |
|
|
|
</ColGroup> |
|
|
|
</ColGroup> |
|
|
|
<HeaderContent> |
|
|
|
<HeaderContent> |
|
|
|
<MudTh> |
|
|
|
<MudTh> |
|
|
|
<MudTableSortLabel SortBy="new Func<PlayoutViewModel, object>(x => decimal.Parse(x.Channel.Number))"> |
|
|
|
<MudTableSortLabel SortBy="new Func<PlayoutViewModel, object>(x => decimal.Parse(x.Channel.Number, CultureInfo.InvariantCulture))"> |
|
|
|
Channel |
|
|
|
Channel |
|
|
|
</MudTableSortLabel> |
|
|
|
</MudTableSortLabel> |
|
|
|
</MudTh> |
|
|
|
</MudTh> |
|
|
|
@ -199,8 +203,8 @@ |
|
|
|
<MudTh>Duration</MudTh> |
|
|
|
<MudTh>Duration</MudTh> |
|
|
|
</HeaderContent> |
|
|
|
</HeaderContent> |
|
|
|
<RowTemplate> |
|
|
|
<RowTemplate> |
|
|
|
<MudTd DataLabel="Start">@context.Start.ToString("G")</MudTd> |
|
|
|
<MudTd DataLabel="Start">@context.Start.ToString("G", _dtf)</MudTd> |
|
|
|
<MudTd DataLabel="Finish">@context.Finish.ToString("G")</MudTd> |
|
|
|
<MudTd DataLabel="Finish">@context.Finish.ToString("G", _dtf)</MudTd> |
|
|
|
<MudTd DataLabel="Media Item">@context.Title</MudTd> |
|
|
|
<MudTd DataLabel="Media Item">@context.Title</MudTd> |
|
|
|
<MudTd DataLabel="Duration">@context.Duration</MudTd> |
|
|
|
<MudTd DataLabel="Duration">@context.Duration</MudTd> |
|
|
|
</RowTemplate> |
|
|
|
</RowTemplate> |
|
|
|
@ -214,6 +218,8 @@ |
|
|
|
@code { |
|
|
|
@code { |
|
|
|
private readonly CancellationTokenSource _cts = new(); |
|
|
|
private readonly CancellationTokenSource _cts = new(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private readonly DateTimeFormatInfo _dtf = CultureInfo.CurrentUICulture.DateTimeFormat; |
|
|
|
|
|
|
|
|
|
|
|
private MudTable<PlayoutNameViewModel> _table; |
|
|
|
private MudTable<PlayoutNameViewModel> _table; |
|
|
|
private MudTable<PlayoutItemViewModel> _detailTable; |
|
|
|
private MudTable<PlayoutItemViewModel> _detailTable; |
|
|
|
private int _rowsPerPage = 10; |
|
|
|
private int _rowsPerPage = 10; |
|
|
|
@ -237,15 +243,30 @@ |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void Dispose() |
|
|
|
protected override void OnInitialized() |
|
|
|
{ |
|
|
|
{ |
|
|
|
EntityLocker.OnPlayoutChanged -= ReloadDetailsIfNeeded; |
|
|
|
Courier.Subscribe<PlayoutUpdatedNotification>(HandlePlayoutUpdated); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void Dispose() |
|
|
|
|
|
|
|
{ |
|
|
|
_cts.Cancel(); |
|
|
|
_cts.Cancel(); |
|
|
|
_cts.Dispose(); |
|
|
|
_cts.Dispose(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected override void OnInitialized() => EntityLocker.OnPlayoutChanged += ReloadDetailsIfNeeded; |
|
|
|
public async Task HandlePlayoutUpdated(PlayoutUpdatedNotification notification, CancellationToken cancellationToken) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// only refresh detail table on unlock operations (after playout has been modified) |
|
|
|
|
|
|
|
if (notification.IsLocked == false) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (notification.PlayoutId == _selectedPlayoutId && _detailTable is not null) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
await InvokeAsync(() => _detailTable.ReloadServerData()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await InvokeAsync(StateHasChanged); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected override async Task OnParametersSetAsync() |
|
|
|
protected override async Task OnParametersSetAsync() |
|
|
|
{ |
|
|
|
{ |
|
|
|
@ -320,15 +341,6 @@ |
|
|
|
private async Task ResetPlayout(PlayoutNameViewModel playout) |
|
|
|
private async Task ResetPlayout(PlayoutNameViewModel playout) |
|
|
|
{ |
|
|
|
{ |
|
|
|
await WorkerChannel.WriteAsync(new BuildPlayout(playout.PlayoutId, PlayoutBuildMode.Reset), _cts.Token); |
|
|
|
await WorkerChannel.WriteAsync(new BuildPlayout(playout.PlayoutId, PlayoutBuildMode.Reset), _cts.Token); |
|
|
|
if (_table != null) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
await _table.ReloadServerData(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (_selectedPlayoutId == playout.PlayoutId) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
await PlayoutSelected(playout); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private async Task ScheduleReset(PlayoutNameViewModel playout) |
|
|
|
private async Task ScheduleReset(PlayoutNameViewModel playout) |
|
|
|
@ -356,7 +368,7 @@ |
|
|
|
await Mediator.Send(new SaveConfigElementByKey(ConfigElementKey.PlayoutsPageSize, state.PageSize.ToString()), _cts.Token); |
|
|
|
await Mediator.Send(new SaveConfigElementByKey(ConfigElementKey.PlayoutsPageSize, state.PageSize.ToString()), _cts.Token); |
|
|
|
|
|
|
|
|
|
|
|
List<PlayoutNameViewModel> playouts = await Mediator.Send(new GetAllPlayouts(), _cts.Token); |
|
|
|
List<PlayoutNameViewModel> playouts = await Mediator.Send(new GetAllPlayouts(), _cts.Token); |
|
|
|
IOrderedEnumerable<PlayoutNameViewModel> sorted = playouts.OrderBy(p => decimal.Parse(p.ChannelNumber)); |
|
|
|
IOrderedEnumerable<PlayoutNameViewModel> sorted = playouts.OrderBy(p => decimal.Parse(p.ChannelNumber, CultureInfo.InvariantCulture)); |
|
|
|
|
|
|
|
|
|
|
|
// TODO: properly page this data |
|
|
|
// TODO: properly page this data |
|
|
|
return new TableData<PlayoutNameViewModel> |
|
|
|
return new TableData<PlayoutNameViewModel> |
|
|
|
@ -366,16 +378,6 @@ |
|
|
|
}; |
|
|
|
}; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private async void ReloadDetailsIfNeeded(object sender, int playoutId) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (playoutId == _selectedPlayoutId && _detailTable is not null) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
await InvokeAsync(() => _detailTable.ReloadServerData()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await InvokeAsync(StateHasChanged); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private async Task<TableData<PlayoutItemViewModel>> DetailServerReload(TableState state, CancellationToken cancellationToken) |
|
|
|
private async Task<TableData<PlayoutItemViewModel>> DetailServerReload(TableState state, CancellationToken cancellationToken) |
|
|
|
{ |
|
|
|
{ |
|
|
|
await Mediator.Send(new SaveConfigElementByKey(ConfigElementKey.PlayoutsDetailPageSize, state.PageSize.ToString()), _cts.Token); |
|
|
|
await Mediator.Send(new SaveConfigElementByKey(ConfigElementKey.PlayoutsDetailPageSize, state.PageSize.ToString()), _cts.Token); |
|
|
|
|