diff --git a/src/EventLogExpert.UI/Models/FilterDateModel.cs b/src/EventLogExpert.UI/Models/FilterDateModel.cs index 68fe4bf7..cab750d5 100644 --- a/src/EventLogExpert.UI/Models/FilterDateModel.cs +++ b/src/EventLogExpert.UI/Models/FilterDateModel.cs @@ -5,11 +5,9 @@ namespace EventLogExpert.UI.Models; public sealed record FilterDateModel { - public DateTime After { get; set; } + public DateTime? After { get; set; } - public DateTime Before { get; set; } - - public TimeZoneInfo TimeZoneInfo { get; set; } = null!; + public DateTime? Before { get; set; } public bool IsEnabled { get; set; } = true; } diff --git a/src/EventLogExpert.UI/Store/FilterPane/FilterPaneAction.cs b/src/EventLogExpert.UI/Store/FilterPane/FilterPaneAction.cs index 8cc01870..c54d1805 100644 --- a/src/EventLogExpert.UI/Store/FilterPane/FilterPaneAction.cs +++ b/src/EventLogExpert.UI/Store/FilterPane/FilterPaneAction.cs @@ -25,6 +25,8 @@ public sealed record SetFilter(FilterModel FilterModel); public sealed record SetFilterDateRange(FilterDateModel? FilterDateModel); + public sealed record SetFilterDateRangeSuccess(FilterDateModel? FilterDateModel); + public sealed record ToggleFilterEditing(FilterId Id); public sealed record ToggleFilterEnabled(FilterId Id); diff --git a/src/EventLogExpert.UI/Store/FilterPane/FilterPaneEffects.cs b/src/EventLogExpert.UI/Store/FilterPane/FilterPaneEffects.cs index dfe3d8e1..89578041 100644 --- a/src/EventLogExpert.UI/Store/FilterPane/FilterPaneEffects.cs +++ b/src/EventLogExpert.UI/Store/FilterPane/FilterPaneEffects.cs @@ -10,7 +10,9 @@ namespace EventLogExpert.UI.Store.FilterPane; -public sealed class FilterPaneEffects(IState filterPaneState) +public sealed class FilterPaneEffects( + IState eventLogState, + IState filterPaneState) { [EffectMethod] public async Task HandleAddFilter(FilterPaneAction.AddFilter action, IDispatcher dispatcher) @@ -74,8 +76,58 @@ public async Task HandleSetFilter(FilterPaneAction.SetFilter action, IDispatcher } } - [EffectMethod(typeof(FilterPaneAction.SetFilterDateRange))] - public async Task HandleSetFilterDateRange(IDispatcher dispatcher) => + [EffectMethod] + public Task HandleSetFilterDateRange(FilterPaneAction.SetFilterDateRange action, IDispatcher dispatcher) + { + if (action.FilterDateModel is null) + { + dispatcher.Dispatch(new FilterPaneAction.SetFilterDateRangeSuccess(action.FilterDateModel)); + + return Task.CompletedTask; + } + + DateTime? updatedAfter = action.FilterDateModel?.After ?? filterPaneState.Value.FilteredDateRange?.After; + DateTime? updatedBefore = action.FilterDateModel?.Before ?? filterPaneState.Value.FilteredDateRange?.Before; + + long ticksPerHour = TimeSpan.FromHours(1).Ticks; + + if (updatedAfter is null) + { + long ticks = + (eventLogState.Value.ActiveLogs.Values.Select(log => log.Events.LastOrDefault()?.TimeCreated) + .Order() + .LastOrDefault() ?? + DateTime.UtcNow) + .Ticks; + + updatedAfter = new DateTime(ticks / ticksPerHour * ticksPerHour, DateTimeKind.Utc); + } + + if (updatedBefore is null) + { + long ticks = + (eventLogState.Value.ActiveLogs.Values.Select(log => log.Events.FirstOrDefault()?.TimeCreated) + .Order() + .FirstOrDefault() ?? + DateTime.UtcNow) + .Ticks; + + updatedBefore = new DateTime((ticks + ticksPerHour - 1) / ticksPerHour * ticksPerHour, DateTimeKind.Utc); + } + + dispatcher.Dispatch( + new FilterPaneAction.SetFilterDateRangeSuccess( + new FilterDateModel + { + After = updatedAfter, + Before = updatedBefore + })); + + return Task.CompletedTask; + } + + [EffectMethod(typeof(FilterPaneAction.SetFilterDateRangeSuccess))] + public async Task HandleSetFilterDateRangeSuccess(IDispatcher dispatcher) => await UpdateEventTableFiltersAsync(filterPaneState.Value, dispatcher); [EffectMethod(typeof(FilterPaneAction.ToggleFilterDate))] diff --git a/src/EventLogExpert.UI/Store/FilterPane/FilterPaneReducers.cs b/src/EventLogExpert.UI/Store/FilterPane/FilterPaneReducers.cs index f8cdeec6..013f5b50 100644 --- a/src/EventLogExpert.UI/Store/FilterPane/FilterPaneReducers.cs +++ b/src/EventLogExpert.UI/Store/FilterPane/FilterPaneReducers.cs @@ -99,8 +99,9 @@ .. state.Filters }; [ReducerMethod] - public static FilterPaneState - ReduceSetFilterDateRange(FilterPaneState state, FilterPaneAction.SetFilterDateRange action) => + public static FilterPaneState ReduceSetFilterDateRangeSuccess( + FilterPaneState state, + FilterPaneAction.SetFilterDateRangeSuccess action) => state with { FilteredDateRange = action.FilterDateModel }; [ReducerMethod(typeof(FilterPaneAction.ToggleFilterDate))] diff --git a/src/EventLogExpert/Components/FilterPane.razor.cs b/src/EventLogExpert/Components/FilterPane.razor.cs index 46b62aab..c7a70813 100644 --- a/src/EventLogExpert/Components/FilterPane.razor.cs +++ b/src/EventLogExpert/Components/FilterPane.razor.cs @@ -15,9 +15,10 @@ namespace EventLogExpert.Components; public sealed partial class FilterPane { - private readonly FilterDateModel _model = new() { TimeZoneInfo = TimeZoneInfo.Utc }; + private readonly FilterDateModel _model = new(); private bool _canEditDate; + private TimeZoneInfo _currentTimeZone = TimeZoneInfo.Utc; private bool _isFilterListVisible; [Inject] private IDispatcher Dispatcher { get; init; } = null!; @@ -34,36 +35,40 @@ public sealed partial class FilterPane [Inject] private IState SettingsState { get; init; } = null!; - [Inject] private IStateSelection TimeZoneState { get; init; } = null!; + [Inject] private IStateSelection TimeZoneState { get; init; } = null!; protected override void OnInitialized() { SubscribeToAction(action => { _canEditDate = false; }); + SubscribeToAction(action => { UpdateFilterDate(action.FilterDateModel); }); - TimeZoneState.Select(x => x.Config.TimeZoneId); - TimeZoneState.SelectedValueChanged += (sender, args) => { UpdateFilterDateModel(); }; + TimeZoneState.Select(x => x.Config.TimeZoneInfo, selectedValueChanged: UpdateFilterDateTimeZone); base.OnInitialized(); } private void AddAdvancedFilter() { - Dispatcher.Dispatch(new FilterPaneAction.AddFilter(new FilterModel - { - FilterType = FilterType.Advanced, - IsEditing = true - })); + Dispatcher.Dispatch( + new FilterPaneAction.AddFilter( + new FilterModel + { + FilterType = FilterType.Advanced, + IsEditing = true + })); _isFilterListVisible = true; } private void AddBasicFilter() { - Dispatcher.Dispatch(new FilterPaneAction.AddFilter(new FilterModel - { - FilterType = FilterType.Basic, - IsEditing = true - })); + Dispatcher.Dispatch( + new FilterPaneAction.AddFilter( + new FilterModel + { + FilterType = FilterType.Basic, + IsEditing = true + })); _isFilterListVisible = true; } @@ -72,7 +77,7 @@ private void AddBasicFilter() private void AddDateFilter() { - _model.TimeZoneInfo = SettingsState.Value.Config.TimeZoneInfo; + _currentTimeZone = SettingsState.Value.Config.TimeZoneInfo; long ticksPerHour = TimeSpan.FromHours(1).Ticks; @@ -92,11 +97,11 @@ private void AddDateFilter() // Round down to the nearest hour for the earliest event _model.After = new DateTime(oldestEventTicks / ticksPerHour * ticksPerHour, DateTimeKind.Utc) - .ConvertTimeZone(SettingsState.Value.Config.TimeZoneInfo); + .ConvertTimeZone(_currentTimeZone); // Round up to the nearest hour for the latest event _model.Before = new DateTime(((mostRecentEventTicks + ticksPerHour - 1) / ticksPerHour) * ticksPerHour, DateTimeKind.Utc) - .ConvertTimeZone(SettingsState.Value.Config.TimeZoneInfo); + .ConvertTimeZone(_currentTimeZone); _isFilterListVisible = true; _canEditDate = true; @@ -104,25 +109,27 @@ private void AddDateFilter() private void AddExclusion() { - Dispatcher.Dispatch(new FilterPaneAction.AddFilter(new FilterModel - { - FilterType = FilterType.Basic, - IsEditing = true, - IsExcluded = true - })); + Dispatcher.Dispatch( + new FilterPaneAction.AddFilter( + new FilterModel + { + FilterType = FilterType.Basic, + IsEditing = true, + IsExcluded = true + })); _isFilterListVisible = true; } private void ApplyDateFilter() { - FilterDateModel model = new() - { - After = _model.After.ConvertTimeZoneToUtc(SettingsState.Value.Config.TimeZoneInfo), - Before = _model.Before.ConvertTimeZoneToUtc(SettingsState.Value.Config.TimeZoneInfo) - }; - - Dispatcher.Dispatch(new FilterPaneAction.SetFilterDateRange(model)); + Dispatcher.Dispatch( + new FilterPaneAction.SetFilterDateRange( + new FilterDateModel + { + After = _model.After?.ConvertTimeZoneToUtc(_currentTimeZone), + Before = _model.Before?.ConvertTimeZoneToUtc(_currentTimeZone) + })); _canEditDate = false; } @@ -149,12 +156,20 @@ private void RemoveDateFilter() private void ToggleMenu() => _isFilterListVisible = !_isFilterListVisible; - private void UpdateFilterDateModel() + private void UpdateFilterDate(FilterDateModel? updatedDate) { - var temp = _model.TimeZoneInfo; - _model.TimeZoneInfo = SettingsState.Value.Config.TimeZoneInfo; + _model.Before = updatedDate?.Before?.ConvertTimeZone(_currentTimeZone); + _model.After = updatedDate?.After?.ConvertTimeZone(_currentTimeZone); + } + + private void UpdateFilterDateTimeZone(TimeZoneInfo timeZoneInfo) + { + _model.Before = _model.Before is not null ? + TimeZoneInfo.ConvertTime(_model.Before.Value, _currentTimeZone, timeZoneInfo) : null; + + _model.After = _model.After is not null ? + TimeZoneInfo.ConvertTime(_model.After.Value, _currentTimeZone, timeZoneInfo) : null; - _model.Before = TimeZoneInfo.ConvertTime(_model.Before, temp, _model.TimeZoneInfo); - _model.After = TimeZoneInfo.ConvertTime(_model.After, temp, _model.TimeZoneInfo); + _currentTimeZone = timeZoneInfo; } } diff --git a/src/EventLogExpert/Shared/Components/ContextMenu.razor b/src/EventLogExpert/Shared/Components/ContextMenu.razor index b784db5c..592a8fa9 100644 --- a/src/EventLogExpert/Shared/Components/ContextMenu.razor +++ b/src/EventLogExpert/Shared/Components/ContextMenu.razor @@ -8,6 +8,11 @@
+
Exclude Events Before
+
Exclude Events After
+ +
+