diff --git a/src/ScriptRunner/ScriptRunner.GUI/ViewModels/ExecutionLogAction.cs b/src/ScriptRunner/ScriptRunner.GUI/ViewModels/ExecutionLogAction.cs new file mode 100644 index 0000000..7dea5b7 --- /dev/null +++ b/src/ScriptRunner/ScriptRunner.GUI/ViewModels/ExecutionLogAction.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.Json.Serialization; +using Avalonia.Controls.Documents; +using Avalonia.Media; +using DynamicData; + +namespace ScriptRunner.GUI.ViewModels; + +public record ExecutionLogAction(DateTime Timestamp, string Source, string Name, Dictionary Parameters) +{ + [JsonIgnore] + public InlineCollection ParametersDescription => new InlineCollection() + { + new Run("["), + + Parameters.SelectMany((x,i) => + { + var value = x.Value?.StartsWith("!!vault:") == true ? "*****" : x.Value; + return new[] + { + new Run($"{x.Key} = "), + new Run(value) + { + Foreground = Brushes.LightGreen, + }, + new Run( i< Parameters.Count -1?", ":"") + }; + }), + new Run("]"), + }; + + public string ParametersDescriptionString() => string.Join(", ", Parameters.OrderBy(x=>x.Key).Select(x => $"{x.Key} = {x.Value}")); +}; \ No newline at end of file diff --git a/src/ScriptRunner/ScriptRunner.GUI/ViewModels/MainWindowViewModel.cs b/src/ScriptRunner/ScriptRunner.GUI/ViewModels/MainWindowViewModel.cs index 2f592bd..b88ab60 100644 --- a/src/ScriptRunner/ScriptRunner.GUI/ViewModels/MainWindowViewModel.cs +++ b/src/ScriptRunner/ScriptRunner.GUI/ViewModels/MainWindowViewModel.cs @@ -8,15 +8,12 @@ using System.Reactive.Linq; using System.Security.Principal; using System.Text.Json; -using System.Text.Json.Serialization; using System.Threading.Tasks; using Avalonia; using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; -using Avalonia.Controls.Documents; using Avalonia.Input; using Avalonia.Input.Platform; -using Avalonia.Media; using Avalonia.Threading; using CliWrap; using DynamicData; @@ -206,6 +203,7 @@ public bool ShowNewVersionAvailable public MainWindowViewModel(ParamsPanelFactory paramsPanelFactory, VaultProvider vaultProvider) { + CompactedHistoryForCurrent = true; this._configRepositoryUpdater = new ConfigRepositoryUpdater(new CliRepositoryClient(command => { var tcs = new TaskCompletionSource(); @@ -294,16 +292,40 @@ public MainWindowViewModel(ParamsPanelFactory paramsPanelFactory, VaultProvider h => this.ExecutionLog.CollectionChanged -= h) .Select(_ => Unit.Default) // We don't care about the event args; we just want to know something changed. .StartWith(Unit.Default) // To ensure initial population. - .CombineLatest(this.WhenAnyValue(x => x.SelectedAction).Where(x => x != null), + .CombineLatest( + this.WhenAnyValue( + x => x.SelectedAction, + x=>x.CompactedHistoryForCurrent, + x=>x.TermForCurrentHistoryFilter + ).Where(x => x.Item1 != null).Throttle(TimeSpan.FromMilliseconds(200)), (_, selectedAction) => selectedAction) - .Select(selectedAction => + .Select(data => { - return this.ExecutionLog - .Where(y => y.Source == selectedAction.SourceName && y.Name == selectedAction.Name); + var (selectedAction, compacted, term) = data; + var filtered = this.ExecutionLog.Where(y => y.Source == selectedAction!.SourceName && y.Name == selectedAction.Name); + + if (compacted) + { + filtered = filtered.GroupBy(x => x.ParametersDescriptionString(), (key, group) => group.First()); + } + + if (string.IsNullOrWhiteSpace(term) == false) + { + filtered = filtered.Where(x => x.Parameters.Values.Any(p => p?.Contains(term, StringComparison.InvariantCultureIgnoreCase) == true)); + } + + return filtered; }) .ObserveOn(RxApp.MainThreadScheduler) .ToProperty(this, x => x.ExecutionLogForCurrent, out _executionLogForCurrent); - + + this.WhenAnyValue(x => x.SelectedAction) + .ObserveOn(RxApp.MainThreadScheduler) + .Subscribe(s => + { + TermForCurrentHistoryFilter = ""; + }); + _appUpdateScheduler = new RealTimeScheduler(TimeSpan.FromDays(1), TimeSpan.FromHours(1), async () => { @@ -323,6 +345,23 @@ public MainWindowViewModel(ParamsPanelFactory paramsPanelFactory, VaultProvider BuildUi(); } + private bool _compactedHistoryForCurrent; + + public bool CompactedHistoryForCurrent + { + get => _compactedHistoryForCurrent; + set => this.RaiseAndSetIfChanged(ref _compactedHistoryForCurrent, value); + } + + private string _termForCurrentHistoryFilter; + + public string TermForCurrentHistoryFilter + { + get => _termForCurrentHistoryFilter; + set => this.RaiseAndSetIfChanged(ref _termForCurrentHistoryFilter, value); + } + + private async Task RefreshInfoAbouAppUpdates() { var isNewerVersion = await appUpdater.CheckIsNewerVersionAvailable(); @@ -922,30 +961,6 @@ private static string[] SplitCommand(string command) } } -public record ExecutionLogAction(DateTime Timestamp, string Source, string Name, Dictionary Parameters) -{ - [JsonIgnore] - public InlineCollection ParametersDescription => new InlineCollection() - { - new Run("["), - - Parameters.SelectMany((x,i) => - { - var value = x.Value?.StartsWith("!!vault:") == true ? "*****" : x.Value; - return new[] - { - new Run($"{x.Key} = "), - new Run(value) - { - Foreground = Brushes.LightGreen, - }, - new Run( i< Parameters.Count -1?", ":"") - }; - }), - new Run("]"), - }; -}; - public record RecentAction(ActionId ActionId, DateTime Timestamp); public record ActionId(string SourceName, string ActionName, string ParameterSet); diff --git a/src/ScriptRunner/ScriptRunner.GUI/Views/ActionDetailsSection.axaml b/src/ScriptRunner/ScriptRunner.GUI/Views/ActionDetailsSection.axaml index 368803c..48f8962 100644 --- a/src/ScriptRunner/ScriptRunner.GUI/Views/ActionDetailsSection.axaml +++ b/src/ScriptRunner/ScriptRunner.GUI/Views/ActionDetailsSection.axaml @@ -180,19 +180,23 @@ - - - - - - - - - - - - - + + + + Compacted + + + + + + + + + + + + +