Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify date filtering #112

Merged
merged 7 commits into from
May 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 26 additions & 7 deletions src/EventLogExpert/Components/EventTable.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,35 @@ protected override async Task OnAfterRenderAsync(bool firstRender)
await base.OnAfterRenderAsync(firstRender);
}

protected override void OnInitialized()
{
MaximumStateChangedNotificationsPerSecond = 2;
base.OnInitialized();
}

private string GetCss(DisplayEventModel @event) => EventLogState.Value.SelectedEvent?.RecordId == @event.RecordId ?
"table-row selected" : "table-row";

private IList<DisplayEventModel> GetFilteredEvents() => EventLogState.Value.Events
.Where(e => e.TimeCreated >= FilterPaneState.Value.FilteredDateRange.After &&
e.TimeCreated <= FilterPaneState.Value.FilteredDateRange.Before)
.Where(e => FilterPaneState.Value.AppliedFilters
.All(filter => filter.Comparison
.Any(comp => comp(e))))
.ToList();
private IList<DisplayEventModel> GetFilteredEvents()
{
var filteredEvents = EventLogState.Value.Events.AsQueryable();

if (FilterPaneState.Value.FilteredDateRange is not null)
{
filteredEvents = filteredEvents.Where(e =>
e.TimeCreated >= FilterPaneState.Value.FilteredDateRange.After &&
e.TimeCreated <= FilterPaneState.Value.FilteredDateRange.Before);
}

if (FilterPaneState.Value.AppliedFilters.Any())
{
filteredEvents = filteredEvents.Where(e => FilterPaneState.Value.AppliedFilters
.All(filter => filter.Comparison
.Any(comp => comp(e))));
}

return filteredEvents.ToList();
}

private void SelectEvent(DisplayEventModel @event) => Dispatcher.Dispatch(new EventLogAction.SelectEvent(@event));
}
69 changes: 46 additions & 23 deletions src/EventLogExpert/Components/FilterPane.razor
Original file line number Diff line number Diff line change
@@ -1,49 +1,72 @@
@using EventLogExpert.Shared.Components

@inherits FluxorComponent

@inject IState<AvailableFilterState> AvailableFilterState
@inject IState<EventLogState> EventLogState
@inject IState<FilterPaneState> FilterPaneState
@inject IState<SettingsState> SettingsState

<div class="filter-pane">

<div class="filter-row">

<div>
<button class="button-primary" @onclick="AddFilter">
<i class="bi bi-plus-circle"></i> Add Filter
</button>
</div>

<div class="header-center">
@if (FilterPaneState.Value.CurrentFilters.Any())
@if (!_isDateFilterVisible)
{
<span>[Active Filters: @FilterPaneState.Value.CurrentFilters.Count()]</span>
<button class="button-primary" @onclick="AddDateFilter">
<i class="bi bi-plus-circle"></i> Add Date Filter
</button>
}
</div>

@if (FilterPaneState.Value.CurrentFilters.Any() || _isDateFilterVisible)
{
<div class="header-center">
@if (FilterPaneState.Value.CurrentFilters.Any())
{
<span>[Active Filters: @FilterPaneState.Value.CurrentFilters.Count()]</span>
}
</div>

<span class="button-toggle header-justify-right" data-rotate="@MenuState" @onclick="ToggleMenu">
<i class="bi bi-caret-up"></i>
</span>
<span class="button-toggle header-justify-right" data-rotate="@MenuState" @onclick="ToggleMenu">
<i class="bi bi-caret-up"></i>
</span>
}
</div>

<div class="filter-content" data-toggle="@MenuState">
<EditForm id="filter-form" Model="_model" OnValidSubmit="ApplyDateFilter">
<span>
After: <InputDate class="input-filter-datetime" Type="InputDateType.DateTimeLocal" @bind-Value="_model.After" />
</span>
<span>
Before: <InputDate class="input-filter-datetime" Type="InputDateType.DateTimeLocal" @bind-Value="_model.Before" />
</span>
@if (_isDateFilterVisible)
{
<EditForm id="filter-form" Model="_model">
<span>
After: <InputDate class="input-filter-datetime" Type="InputDateType.DateTimeLocal"
@bind-Value="_model.After" disabled="@(!_canEditDate)" />
</span>
<span>
Before: <InputDate class="input-filter-datetime" Type="InputDateType.DateTimeLocal"
@bind-Value="_model.Before" disabled="@(!_canEditDate)" />
</span>

<button class="button-save" type="submit">
<i class="bi bi-check-circle"></i> Apply
</button>
<button class="button-remove" type="button" @onclick="ResetDateFilter">
<i class="bi bi-dash-circle"></i> Reset
</button>
</EditForm>
@if (_canEditDate)
{
<button class="button-save" @onclick="ApplyDateFilter">
<i class="bi bi-check-circle"></i> Apply
</button>
}
else
{
<button class="button-save" @onclick="EditDateFilter">
<i class="bi bi-funnel"></i> Edit
</button>
}
<button class="button-remove" type="button" @onclick="RemoveDateFilter">
<i class="bi bi-dash-circle"></i> Remove
</button>
</EditForm>
}

@foreach (var item in FilterPaneState.Value.CurrentFilters)
{
Expand Down
65 changes: 35 additions & 30 deletions src/EventLogExpert/Components/FilterPane.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,60 +10,65 @@ public partial class FilterPane
{
private readonly FilterDateModel _model = new();

private FilterDateModel? _availableRange;
private bool _canEditDate = true;
private bool _isDateFilterVisible;
private bool _isFilterListVisible;

private bool _expandMenu;
private string MenuState
{
get
{
if (FilterPaneState.Value.CurrentFilters.Any() || _isDateFilterVisible)
{
return _isFilterListVisible.ToString().ToLower();
}

private string MenuState => _expandMenu.ToString().ToLower();
return "false";
}
}

protected override void OnInitialized()
private void AddDateFilter()
{
AvailableFilterState.StateChanged += (sender, args) =>
{
_availableRange = AvailableFilterState.Value.EventDateRange;
ResetDateModel();
ApplyDateFilter();
};
_isFilterListVisible = true;
_canEditDate = true;

// Offset by 1 minute to make sure we don't drop events
// since HTML input DateTime does not go lower than minutes
_model.Before = EventLogState.Value.Events.FirstOrDefault()?.TimeCreated
.AddMinutes(1).ConvertTimeZone(SettingsState.Value.TimeZone) ??
DateTime.Now;

SettingsState.StateChanged += (sender, args) => { ResetDateModel(); };
_model.After = EventLogState.Value.Events.LastOrDefault()?.TimeCreated
.AddMinutes(-1).ConvertTimeZone(SettingsState.Value.TimeZone) ??
DateTime.Now;

base.OnInitialized();
_isDateFilterVisible = true;
}

private void AddFilter()
{
Dispatcher.Dispatch(new FilterPaneAction.AddFilter());
_expandMenu = true;
_isFilterListVisible = true;
}

private void ApplyDateFilter()
{
FilterDateModel model = new()
{
After = _model.After.ToUniversalTime(),
Before = _model.Before.ToUniversalTime()
After = _model.After.ToUniversalTime(), Before = _model.Before.ToUniversalTime()
};

Dispatcher.Dispatch(new FilterPaneAction.SetFilterDateRange(model));
_canEditDate = false;
}

private void ResetDateFilter()
private void RemoveDateFilter()
{
if (_availableRange is null) { return; }

Dispatcher.Dispatch(new FilterPaneAction.SetFilterDateRange(_availableRange));
ResetDateModel();
Dispatcher.Dispatch(new FilterPaneAction.SetFilterDateRange(null));
_isDateFilterVisible = false;
}

private void ResetDateModel()
{
// Adding 1 minute offset because DateTime input does not include seconds so we don't want to drop events
_model.After = _availableRange?.After.AddMinutes(-1).ConvertTimeZone(SettingsState.Value.TimeZone) ??
DateTime.Now;

_model.Before = _availableRange?.Before.AddMinutes(1).ConvertTimeZone(SettingsState.Value.TimeZone) ??
DateTime.Now;
}
private void EditDateFilter() => _canEditDate = true;

private void ToggleMenu() => _expandMenu = !_expandMenu;
private void ToggleMenu() => _isFilterListVisible = !_isFilterListVisible;
}
1 change: 0 additions & 1 deletion src/EventLogExpert/MainPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ public async void OpenFile_Clicked(object sender, EventArgs e)
OpenEventLogFile(result.FullPath);
}
}

private void CheckForUpdates_Clicked(object? sender, EventArgs e) =>
_fluxorDispatcher.Dispatch(new SettingsAction.CheckForUpdates());

Expand Down
13 changes: 0 additions & 13 deletions src/EventLogExpert/Store/EventLog/EventLogEffects.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using EventLogExpert.Library.EventResolvers;
using EventLogExpert.Library.Helpers;
using EventLogExpert.Library.Models;
using EventLogExpert.Store.FilterPane;
using EventLogExpert.Store.StatusBar;
using Fluxor;
using System.Collections.Immutable;
Expand All @@ -25,18 +24,6 @@ public EventLogEffects(IEventResolver eventResolver, ITraceLogger debugLogger)
_debugLogger = debugLogger;
}

[EffectMethod]
public async Task HandleLoadEventsAction(EventLogAction.LoadEvents action, IDispatcher dispatcher)
{
FilterDateModel filterDateModel = new()
{
After = action.Events.Last().TimeCreated,
Before = action.Events.First().TimeCreated
};

dispatcher.Dispatch(new FilterPaneAction.SetFilterDateRange(filterDateModel));
}

[EffectMethod]
public async Task HandleOpenLogAction(EventLogAction.OpenLog action, IDispatcher dispatcher)
{
Expand Down
2 changes: 1 addition & 1 deletion src/EventLogExpert/Store/EventLog/EventLogReducers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class EventLogReducers
/// The maximum number of new events we will hold in the state
/// before we turn off the watcher.
/// </summary>
private static readonly int MaxNewEvents = 5000;
private static readonly int MaxNewEvents = 1000;

[ReducerMethod]
public static EventLogState ReduceAddEvent(EventLogState state, EventLogAction.AddEvent action)
Expand Down
2 changes: 1 addition & 1 deletion src/EventLogExpert/Store/FilterPane/FilterPaneAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ public record RemoveSubFilter(Guid ParentId, SubFilterModel SubFilterModel);

public record ApplyFilters;

public record SetFilterDateRange(FilterDateModel FilterDateModel);
public record SetFilterDateRange(FilterDateModel? FilterDateModel);
}
2 changes: 1 addition & 1 deletion src/EventLogExpert/Store/FilterPane/FilterPaneState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ public record FilterPaneState

public IEnumerable<FilterModel> AppliedFilters { get; init; } = Enumerable.Empty<FilterModel>();

public FilterDateModel FilteredDateRange { get; init; } = new();
public FilterDateModel? FilteredDateRange { get; init; } = null;
}