From fe04953854d0d04f6e828bbd35c3f175ebe7c1e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cezary=20Pi=C4=85tek?= Date: Thu, 12 Feb 2026 19:28:33 +0100 Subject: [PATCH 1/6] Fix issue with selecting action from search while there are active filters --- .../ScriptRunner.GUI/Views/SideMenu.axaml.cs | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/ScriptRunner/ScriptRunner.GUI/Views/SideMenu.axaml.cs b/src/ScriptRunner/ScriptRunner.GUI/Views/SideMenu.axaml.cs index 3822857..84a3119 100644 --- a/src/ScriptRunner/ScriptRunner.GUI/Views/SideMenu.axaml.cs +++ b/src/ScriptRunner/ScriptRunner.GUI/Views/SideMenu.axaml.cs @@ -83,17 +83,13 @@ private async void OpenSearchBox(object? sender, RoutedEventArgs e) if (pattern.EventArgs is SearchBox.ResultSelectedEventArgs {Result: { } selectedCommand, AutoLaunch: var autoLaunch}) { - var selectedTagged = viewModel.FilteredActionList.SelectMany(x => x.Children) - .FirstOrDefault(x => x.Config == selectedCommand.Config); - - if (selectedTagged != null) + // Set SelectedAction directly (same pattern as ExecutionLog selection) + // This works regardless of any active category filter + viewModel.SelectedAction = selectedCommand.Config; + viewModel.SelectedArgumentSet = selectedCommand.ArgumentSet; + if (autoLaunch) { - viewModel.SelectedActionOrGroup = selectedTagged; - viewModel.SelectedArgumentSet = selectedCommand.ArgumentSet; - if (autoLaunch) - { - viewModel.RunScript(); - } + viewModel.RunScript(); } } }); From 723a8a60329e5ecba1bc3a816150490f3c338d8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cezary=20Pi=C4=85tek?= Date: Thu, 12 Feb 2026 19:47:17 +0100 Subject: [PATCH 2/6] Improve the searchbox layout --- .../ScriptRunner.GUI/Views/SearchBox.axaml | 77 +++++++++++-------- 1 file changed, 44 insertions(+), 33 deletions(-) diff --git a/src/ScriptRunner/ScriptRunner.GUI/Views/SearchBox.axaml b/src/ScriptRunner/ScriptRunner.GUI/Views/SearchBox.axaml index 00f7752..1d052d8 100644 --- a/src/ScriptRunner/ScriptRunner.GUI/Views/SearchBox.axaml +++ b/src/ScriptRunner/ScriptRunner.GUI/Views/SearchBox.axaml @@ -10,62 +10,73 @@ x:Class="ScriptRunner.GUI.Views.SearchBox" x:DataType="viewModels:SearchBoxViewModel"> - - - - - - - - - + + + + + + + + + + + + + + + + + - - - + + + - + - - - - - - + + + + + - + - - - + + + - + - - - + + + - + - - - + + + - + - + From eb4068e5b55ef9de90de5b754b5300300af2c7ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cezary=20Pi=C4=85tek?= Date: Thu, 12 Feb 2026 20:18:18 +0100 Subject: [PATCH 3/6] Include predefined sets in action list --- .../ViewModels/MainWindowViewModel.cs | 80 ++++++++++++++----- .../ViewModels/SearchBoxViewModel.cs | 6 +- .../ScriptRunner.GUI/Views/ActionsList.axaml | 12 +-- .../ScriptRunner.GUI/Views/SearchBox.axaml | 8 +- 4 files changed, 76 insertions(+), 30 deletions(-) diff --git a/src/ScriptRunner/ScriptRunner.GUI/ViewModels/MainWindowViewModel.cs b/src/ScriptRunner/ScriptRunner.GUI/ViewModels/MainWindowViewModel.cs index e27a4e4..258a6f1 100644 --- a/src/ScriptRunner/ScriptRunner.GUI/ViewModels/MainWindowViewModel.cs +++ b/src/ScriptRunner/ScriptRunner.GUI/ViewModels/MainWindowViewModel.cs @@ -215,9 +215,13 @@ public object? SelectedActionOrGroup set { this.RaiseAndSetIfChanged(ref _selectedActionOrGroup, value); - if (value is TaggedScriptConfig {Config: var scriptConfig}) + if (value is TaggedScriptConfig {Config: var scriptConfig, ArgumentSet: var argumentSet}) { SelectedAction = scriptConfig; + if (argumentSet != null) + { + SelectedArgumentSet = argumentSet; + } } } } @@ -393,12 +397,8 @@ public MainWindowViewModel(ParamsPanelFactory paramsPanelFactory, VaultProvider { var (textFilter, categoryFilter, actions) = tuple; - // Apply text filter - var configs = string.IsNullOrWhiteSpace(textFilter) - ? actions - : actions.Where(x => x.Name.Contains(textFilter, StringComparison.InvariantCultureIgnoreCase)); - - // Apply category filter (AND operator with text filter) + // Apply category filter first + IEnumerable configs = actions; if (!string.IsNullOrWhiteSpace(categoryFilter) && categoryFilter != "All") { if (categoryFilter == "(No Category)") @@ -416,19 +416,39 @@ public MainWindowViewModel(ParamsPanelFactory paramsPanelFactory, VaultProvider // When a specific category is filtered, show each action only once under that category if (!string.IsNullOrWhiteSpace(categoryFilter) && categoryFilter != "All") { - scriptConfigGroupWrappers = new[] + var expandedEntries = configs.SelectMany(c => + c.PredefinedArgumentSets.Select(p => new TaggedScriptConfig( + categoryFilter, + p.Description == "" ? c.Name : $"{c.Name} - {p.Description}", + c, + p + )) + ); + + // Apply text filter to expanded entries + if (!string.IsNullOrWhiteSpace(textFilter)) { - new ScriptConfigGroupWrapper + expandedEntries = expandedEntries.Where(x => x.Name.Contains(textFilter, StringComparison.InvariantCultureIgnoreCase)); + } + + var children = expandedEntries.OrderBy(x => x.Name).ToList(); + + // Only create group if it has children + scriptConfigGroupWrappers = children.Any() + ? new[] { - Name = categoryFilter, - Children = configs.Select(c => new TaggedScriptConfig(categoryFilter, c.Name, c)).OrderBy(x => x.Name) + new ScriptConfigGroupWrapper + { + Name = categoryFilter, + Children = children + } } - }; + : Enumerable.Empty(); } else { // When no filter or "All" is selected, show actions grouped by all their categories - scriptConfigGroupWrappers = configs.SelectMany(c => + var groupedConfigs = configs.SelectMany(c => { if (c.Categories is {Count: > 0}) { @@ -436,12 +456,31 @@ public MainWindowViewModel(ParamsPanelFactory paramsPanelFactory, VaultProvider } return new[] {(category: "(No Category)", script: c)}; - }).GroupBy(x => x.category).OrderBy(x=>x.Key) - .Select(x=> new ScriptConfigGroupWrapper + }).GroupBy(x => x.category).OrderBy(x=>x.Key); + + scriptConfigGroupWrappers = groupedConfigs.Select(x => + { + var expandedEntries = x.SelectMany(p => + p.script.PredefinedArgumentSets.Select(argSet => new TaggedScriptConfig( + x.Key, + argSet.Description == "" ? p.script.Name : $"{p.script.Name} - {argSet.Description}", + p.script, + argSet + )) + ); + + // Apply text filter to expanded entries + if (!string.IsNullOrWhiteSpace(textFilter)) + { + expandedEntries = expandedEntries.Where(e => e.Name.Contains(textFilter, StringComparison.InvariantCultureIgnoreCase)); + } + + return new ScriptConfigGroupWrapper { Name = x.Key, - Children = x.Select(p=> new TaggedScriptConfig(x.Key, p.script.Name, p.script)).OrderBy(x=>x.Name) - }); + Children = expandedEntries.OrderBy(e => e.Name) + }; + }).Where(group => group.Children.Any()); // Filter out empty groups } return scriptConfigGroupWrappers; @@ -1448,4 +1487,9 @@ public class ScriptConfigGroupWrapper public IEnumerable Children { get; set; } } -public record TaggedScriptConfig(string Tag, string Name, ScriptConfig Config); +public record TaggedScriptConfig(string Tag, string Name, ScriptConfig Config, ArgumentSet ArgumentSet = null) +{ + public string IconName => "fa-scroll"; + public string IconColor => ArgumentSet?.Description == "" ? "#3baced" : "#ff8c00"; +} + diff --git a/src/ScriptRunner/ScriptRunner.GUI/ViewModels/SearchBoxViewModel.cs b/src/ScriptRunner/ScriptRunner.GUI/ViewModels/SearchBoxViewModel.cs index d8ffc59..8c9512d 100644 --- a/src/ScriptRunner/ScriptRunner.GUI/ViewModels/SearchBoxViewModel.cs +++ b/src/ScriptRunner/ScriptRunner.GUI/ViewModels/SearchBoxViewModel.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Reactive.Linq; @@ -33,7 +33,8 @@ public SearchBoxViewModel(IReadOnlyList allActions, IReadOnlyList< ArgumentSet = p, FullName = p.Description == ""? x.FullName : $"{x.FullName} - {p.Description}", ActionName = p.Description == ""? x.Name : $"{x.Name} - {p.Description}", - SourceName = x.SourceName + SourceName = x.SourceName, + IconColor = p.Description == "" ? "#3baced" : "#ff8c00" })).ToList(); var intial = true; @@ -105,6 +106,7 @@ public class ScriptConfigWithArgumentSet public string FullName { get; set; } public string ActionName { get; set; } public string SourceName { get; set; } + public string IconColor { get; set; } } } diff --git a/src/ScriptRunner/ScriptRunner.GUI/Views/ActionsList.axaml b/src/ScriptRunner/ScriptRunner.GUI/Views/ActionsList.axaml index 70bb807..c487d6c 100644 --- a/src/ScriptRunner/ScriptRunner.GUI/Views/ActionsList.axaml +++ b/src/ScriptRunner/ScriptRunner.GUI/Views/ActionsList.axaml @@ -162,7 +162,7 @@ - + @@ -196,15 +196,15 @@ - - + + @@ -226,7 +226,7 @@ diff --git a/src/ScriptRunner/ScriptRunner.GUI/Views/SearchBox.axaml b/src/ScriptRunner/ScriptRunner.GUI/Views/SearchBox.axaml index 1d052d8..96c9f13 100644 --- a/src/ScriptRunner/ScriptRunner.GUI/Views/SearchBox.axaml +++ b/src/ScriptRunner/ScriptRunner.GUI/Views/SearchBox.axaml @@ -34,10 +34,10 @@ - - - - + + + + From a056ddb55401548d91a1b0d167ed4ad23fb311e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cezary=20Pi=C4=85tek?= Date: Thu, 12 Feb 2026 20:23:57 +0100 Subject: [PATCH 4/6] Fix wrapping for list items --- .../ScriptRunner.GUI/Views/ActionsList.axaml | 10 +++++----- .../ScriptRunner.GUI/Views/SearchBox.axaml | 14 +++++++------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/ScriptRunner/ScriptRunner.GUI/Views/ActionsList.axaml b/src/ScriptRunner/ScriptRunner.GUI/Views/ActionsList.axaml index c487d6c..2cc3780 100644 --- a/src/ScriptRunner/ScriptRunner.GUI/Views/ActionsList.axaml +++ b/src/ScriptRunner/ScriptRunner.GUI/Views/ActionsList.axaml @@ -1,4 +1,4 @@ - - - - + + - + - - - - - - - + + + + + + + From 064adc5503be6b8e9aa54b1f154302adf8134e52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cezary=20Pi=C4=85tek?= Date: Thu, 12 Feb 2026 20:55:25 +0100 Subject: [PATCH 5/6] Add icons to Action menu --- .../Views/ActionDetailsSection.axaml | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/ScriptRunner/ScriptRunner.GUI/Views/ActionDetailsSection.axaml b/src/ScriptRunner/ScriptRunner.GUI/Views/ActionDetailsSection.axaml index ade5412..c128295 100644 --- a/src/ScriptRunner/ScriptRunner.GUI/Views/ActionDetailsSection.axaml +++ b/src/ScriptRunner/ScriptRunner.GUI/Views/ActionDetailsSection.axaml @@ -38,10 +38,26 @@ From 415f63b632be7830a1e3738dd885b01c62aa8293 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cezary=20Pi=C4=85tek?= Date: Thu, 12 Feb 2026 21:08:58 +0100 Subject: [PATCH 6/6] Add action count --- .../ViewModels/MainWindowViewModel.cs | 9 +++++++++ .../ScriptRunner.GUI/Views/ActionsList.axaml | 13 ++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/ScriptRunner/ScriptRunner.GUI/ViewModels/MainWindowViewModel.cs b/src/ScriptRunner/ScriptRunner.GUI/ViewModels/MainWindowViewModel.cs index 258a6f1..26e4e8b 100644 --- a/src/ScriptRunner/ScriptRunner.GUI/ViewModels/MainWindowViewModel.cs +++ b/src/ScriptRunner/ScriptRunner.GUI/ViewModels/MainWindowViewModel.cs @@ -176,6 +176,10 @@ public bool IsTreeViewMode private readonly ObservableAsPropertyHelper> _filteredActionList; public IEnumerable FilteredActionList => _filteredActionList.Value; + private readonly ObservableAsPropertyHelper _actionCount; + public int ActionCount => _actionCount.Value; + + public ObservableCollection RunningJobs { get; set; } = new(); @@ -487,6 +491,11 @@ public MainWindowViewModel(ParamsPanelFactory paramsPanelFactory, VaultProvider }) .ObserveOn(RxApp.MainThreadScheduler) .ToProperty(this, x => x.FilteredActionList, out _filteredActionList); + + this.WhenAnyValue(x => x.Actions) + .Select(list => list?.Count ?? 0) + .ObserveOn(RxApp.MainThreadScheduler) + .ToProperty(this, x => x.ActionCount, out _actionCount); Observable .FromEventPattern( diff --git a/src/ScriptRunner/ScriptRunner.GUI/Views/ActionsList.axaml b/src/ScriptRunner/ScriptRunner.GUI/Views/ActionsList.axaml index 2cc3780..b769514 100644 --- a/src/ScriptRunner/ScriptRunner.GUI/Views/ActionsList.axaml +++ b/src/ScriptRunner/ScriptRunner.GUI/Views/ActionsList.axaml @@ -40,9 +40,10 @@ - + + @@ -258,5 +259,15 @@ + + + + + +