globalization fixes (#2014)

* fix crashes caused by decimal separator

* improvements to playout reset ui

* remove code quality workflow
This commit is contained in:
Jason Dove
2025-05-26 16:32:25 +00:00
committed by GitHub
parent e44a391f00
commit 956734ce39
10 changed files with 54 additions and 66 deletions
+2 -2
View File
@@ -29,7 +29,7 @@
</ColGroup>
<HeaderContent>
<MudTh>
<MudTableSortLabel InitialDirection="SortDirection.Ascending" SortBy="new Func<ChannelViewModel, object>(x => decimal.Parse(x.Number))">Number</MudTableSortLabel>
<MudTableSortLabel InitialDirection="SortDirection.Ascending" SortBy="new Func<ChannelViewModel, object>(x => decimal.Parse(x.Number, CultureInfo.InvariantCulture))">Number</MudTableSortLabel>
</MudTh>
<MudTh>Logo</MudTh>
<MudTh>
@@ -219,7 +219,7 @@
await Mediator.Send(new SaveConfigElementByKey(ConfigElementKey.ChannelsPageSize, state.PageSize.ToString()), _cts.Token);
List<ChannelViewModel> channels = await Mediator.Send(new GetAllChannels(), _cts.Token);
IOrderedEnumerable<ChannelViewModel> sorted = channels.OrderBy(c => decimal.Parse(c.Number));
IOrderedEnumerable<ChannelViewModel> sorted = channels.OrderBy(c => decimal.Parse(c.Number, CultureInfo.InvariantCulture));
CultureInfo[] allCultures = CultureInfo.GetCultures(CultureTypes.NeutralCultures);
var processedChannels = new List<ChannelViewModel>();
+2 -1
View File
@@ -1,5 +1,6 @@
@page "/playouts/add"
@page "/playouts/add/{kind}"
@using System.Globalization
@using ErsatzTV.Application.Channels
@using ErsatzTV.Application.ProgramSchedules
@implements IDisposable
@@ -99,7 +100,7 @@
_model.Kind = Kind;
_channels = await Mediator.Send(new GetAllChannels(), _cts.Token)
.Map(list => list.OrderBy(vm => decimal.Parse(vm.Number)).ToList());
.Map(list => list.OrderBy(vm => decimal.Parse(vm.Number, CultureInfo.InvariantCulture)).ToList());
if (string.IsNullOrWhiteSpace(Kind))
{
+29 -27
View File
@@ -1,12 +1,16 @@
@page "/playouts"
@page "/playouts"
@using System.Globalization
@using ErsatzTV.Application.Configuration
@using ErsatzTV.Application.Playouts
@using ErsatzTV.Core.Scheduling
@using ErsatzTV.Core.Notifications
@using MediatR.Courier
@implements IDisposable
@inject IDialogService Dialog
@inject IMediator Mediator
@inject ChannelWriter<IBackgroundServiceRequest> WorkerChannel
@inject IEntityLocker EntityLocker;
@inject ICourier Courier;
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="pt-8">
<div>
@@ -50,7 +54,7 @@
</ColGroup>
<HeaderContent>
<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
</MudTableSortLabel>
</MudTh>
@@ -199,8 +203,8 @@
<MudTh>Duration</MudTh>
</HeaderContent>
<RowTemplate>
<MudTd DataLabel="Start">@context.Start.ToString("G")</MudTd>
<MudTd DataLabel="Finish">@context.Finish.ToString("G")</MudTd>
<MudTd DataLabel="Start">@context.Start.ToString("G", _dtf)</MudTd>
<MudTd DataLabel="Finish">@context.Finish.ToString("G", _dtf)</MudTd>
<MudTd DataLabel="Media Item">@context.Title</MudTd>
<MudTd DataLabel="Duration">@context.Duration</MudTd>
</RowTemplate>
@@ -214,6 +218,8 @@
@code {
private readonly CancellationTokenSource _cts = new();
private readonly DateTimeFormatInfo _dtf = CultureInfo.CurrentUICulture.DateTimeFormat;
private MudTable<PlayoutNameViewModel> _table;
private MudTable<PlayoutItemViewModel> _detailTable;
private int _rowsPerPage = 10;
@@ -237,15 +243,30 @@
}
}
protected override void OnInitialized()
{
Courier.Subscribe<PlayoutUpdatedNotification>(HandlePlayoutUpdated);
}
public void Dispose()
{
EntityLocker.OnPlayoutChanged -= ReloadDetailsIfNeeded;
_cts.Cancel();
_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()
{
@@ -320,15 +341,6 @@
private async Task ResetPlayout(PlayoutNameViewModel playout)
{
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)
@@ -356,7 +368,7 @@
await Mediator.Send(new SaveConfigElementByKey(ConfigElementKey.PlayoutsPageSize, state.PageSize.ToString()), _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
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)
{
await Mediator.Send(new SaveConfigElementByKey(ConfigElementKey.PlayoutsDetailPageSize, state.PageSize.ToString()), _cts.Token);