From 030fb83b64dbfaaa41247503976a890e36e37d92 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Mon, 12 Jan 2026 20:38:43 +0100 Subject: [PATCH] Refactored assistant visibility --- .../Components/AssistantBlock.razor.cs | 89 ++-------------- .../Settings/DataModel/PreviewFeatures.cs | 2 + .../Tools/AssistantVisibilityExtensions.cs | 100 ++++++++++++++++++ 3 files changed, 112 insertions(+), 79 deletions(-) create mode 100644 app/MindWork AI Studio/Tools/AssistantVisibilityExtensions.cs diff --git a/app/MindWork AI Studio/Components/AssistantBlock.razor.cs b/app/MindWork AI Studio/Components/AssistantBlock.razor.cs index b06d3a94..69dfe49b 100644 --- a/app/MindWork AI Studio/Components/AssistantBlock.razor.cs +++ b/app/MindWork AI Studio/Components/AssistantBlock.razor.cs @@ -1,4 +1,3 @@ -using AIStudio.Settings; using AIStudio.Settings.DataModel; using Microsoft.AspNetCore.Components; @@ -11,16 +10,16 @@ public partial class AssistantBlock : MSGComponentBase where TSetting { [Parameter] public string Name { get; set; } = string.Empty; - + [Parameter] public string Description { get; set; } = string.Empty; - + [Parameter] public string Icon { get; set; } = Icons.Material.Filled.DisabledByDefault; - + [Parameter] public string ButtonText { get; set; } = "Start"; - + [Parameter] public string Link { get; set; } = string.Empty; @@ -28,24 +27,21 @@ public partial class AssistantBlock : MSGComponentBase where TSetting public Tools.Components Component { get; set; } = Tools.Components.NONE; [Parameter] - public PreviewFeatures? RequiredPreviewFeature { get; set; } - + public PreviewFeatures RequiredPreviewFeature { get; set; } = PreviewFeatures.NONE; + [Inject] private MudTheme ColorTheme { get; init; } = null!; - + [Inject] private IDialogService DialogService { get; init; } = null!; - [Inject] - private ILogger> Logger { get; init; } = null!; - private async Task OpenSettingsDialog() { var dialogParameters = new DialogParameters(); - + await this.DialogService.ShowAsync(T("Open Settings"), dialogParameters, DialogOptions.FULLSCREEN); } - + private string BorderColor => this.SettingsManager.IsDarkMode switch { true => this.ColorTheme.GetCurrentPalette(this.SettingsManager).GrayLight, @@ -54,70 +50,5 @@ public partial class AssistantBlock : MSGComponentBase where TSetting private string BlockStyle => $"border-width: 2px; border-color: {this.BorderColor}; border-radius: 12px; border-style: solid; max-width: 20em;"; - private bool IsVisible - { - get - { - // Check if a preview feature is required and enabled: - if (this.RequiredPreviewFeature is { } previewFeature && !previewFeature.IsEnabled(this.SettingsManager)) - { - this.Logger.LogInformation("Assistant '{AssistantName}' is not visible because the required preview feature '{PreviewFeature}' is not enabled.", this.Name, previewFeature); - return false; - } - - // Check if the assistant is visible based on the configuration: - return this.IsAssistantVisible(); - } - } - - /// - /// Checks if an assistant should be visible based on configuration. - /// - /// True if the assistant should be visible, false otherwise. - private bool IsAssistantVisible() - { - // If no component is specified, it's always visible: - if (this.Component is Tools.Components.NONE) - { - this.Logger.LogWarning("Assistant '{AssistantName}' is visible because no component is specified.", this.Name); - return true; - } - - // Map Components enum to ConfigurableAssistant enum: - var configurableAssistant = this.Component switch - { - Tools.Components.GRAMMAR_SPELLING_ASSISTANT => ConfigurableAssistant.GRAMMAR_SPELLING_ASSISTANT, - Tools.Components.ICON_FINDER_ASSISTANT => ConfigurableAssistant.ICON_FINDER_ASSISTANT, - Tools.Components.REWRITE_ASSISTANT => ConfigurableAssistant.REWRITE_ASSISTANT, - Tools.Components.TRANSLATION_ASSISTANT => ConfigurableAssistant.TRANSLATION_ASSISTANT, - Tools.Components.AGENDA_ASSISTANT => ConfigurableAssistant.AGENDA_ASSISTANT, - Tools.Components.CODING_ASSISTANT => ConfigurableAssistant.CODING_ASSISTANT, - Tools.Components.TEXT_SUMMARIZER_ASSISTANT => ConfigurableAssistant.TEXT_SUMMARIZER_ASSISTANT, - Tools.Components.EMAIL_ASSISTANT => ConfigurableAssistant.EMAIL_ASSISTANT, - Tools.Components.LEGAL_CHECK_ASSISTANT => ConfigurableAssistant.LEGAL_CHECK_ASSISTANT, - Tools.Components.SYNONYMS_ASSISTANT => ConfigurableAssistant.SYNONYMS_ASSISTANT, - Tools.Components.MY_TASKS_ASSISTANT => ConfigurableAssistant.MY_TASKS_ASSISTANT, - Tools.Components.JOB_POSTING_ASSISTANT => ConfigurableAssistant.JOB_POSTING_ASSISTANT, - Tools.Components.BIAS_DAY_ASSISTANT => ConfigurableAssistant.BIAS_DAY_ASSISTANT, - Tools.Components.ERI_ASSISTANT => ConfigurableAssistant.ERI_ASSISTANT, - Tools.Components.DOCUMENT_ANALYSIS_ASSISTANT => ConfigurableAssistant.DOCUMENT_ANALYSIS_ASSISTANT, - Tools.Components.I18N_ASSISTANT => ConfigurableAssistant.I18N_ASSISTANT, - - _ => ConfigurableAssistant.UNKNOWN, - }; - - // If the component doesn't map to a configurable assistant, it's always visible: - if (configurableAssistant is ConfigurableAssistant.UNKNOWN) - { - this.Logger.LogWarning("Assistant '{AssistantName}' is visible because its component '{Component}' does not map to a configurable assistant.", this.Name, this.Component); - return true; - } - - // Check if the assistant is hidden by any configuration plugin: - var isHidden = this.SettingsManager.ConfigurationData.App.HiddenAssistants.Contains(configurableAssistant); - if (isHidden) - this.Logger.LogInformation("Assistant '{AssistantName}' is hidden based on configuration.", this.Name); - - return !isHidden; - } + private bool IsVisible => this.SettingsManager.IsAssistantVisible(this.Component, assistantName: this.Name, requiredPreviewFeature: this.RequiredPreviewFeature); } \ No newline at end of file diff --git a/app/MindWork AI Studio/Settings/DataModel/PreviewFeatures.cs b/app/MindWork AI Studio/Settings/DataModel/PreviewFeatures.cs index d74898dd..e58ecdca 100644 --- a/app/MindWork AI Studio/Settings/DataModel/PreviewFeatures.cs +++ b/app/MindWork AI Studio/Settings/DataModel/PreviewFeatures.cs @@ -2,6 +2,8 @@ namespace AIStudio.Settings.DataModel; public enum PreviewFeatures { + NONE = 0, + // // Important: Never delete any enum value from this list. // We must be able to deserialize old settings files that may contain these values. diff --git a/app/MindWork AI Studio/Tools/AssistantVisibilityExtensions.cs b/app/MindWork AI Studio/Tools/AssistantVisibilityExtensions.cs new file mode 100644 index 00000000..cb4e7fdc --- /dev/null +++ b/app/MindWork AI Studio/Tools/AssistantVisibilityExtensions.cs @@ -0,0 +1,100 @@ +using AIStudio.Settings; +using AIStudio.Settings.DataModel; + +namespace AIStudio.Tools; + +/// +/// Extension methods for checking assistant visibility based on configuration and preview features. +/// +public static class AssistantVisibilityExtensions +{ + private static readonly ILogger LOGGER = Program.LOGGER_FACTORY.CreateLogger(nameof(AssistantVisibilityExtensions)); + + /// + /// Checks if an assistant should be visible based on configuration and optional preview feature requirements. + /// + /// The settings manager to check configuration against. + /// Whether to log visibility decisions. + /// The name of the assistant to check (for logging purposes). + /// The assistant component to check. + /// Optional preview feature that must be enabled for the assistant to be visible. + /// True if the assistant should be visible, false otherwise. + public static bool IsAssistantVisible(this SettingsManager settingsManager, Components component, bool withLogging = true, string assistantName = "", PreviewFeatures requiredPreviewFeature = PreviewFeatures.NONE) + { + withLogging = withLogging && !string.IsNullOrWhiteSpace(assistantName); + + // Check if a preview feature is required and enabled: + if (requiredPreviewFeature != PreviewFeatures.NONE && !requiredPreviewFeature.IsEnabled(settingsManager)) + { + if(withLogging) + LOGGER.LogInformation("Assistant '{AssistantName}' is not visible because the required preview feature '{PreviewFeature}' is not enabled.", assistantName, requiredPreviewFeature); + + return false; + } + + // If no component is specified, it's always visible: + if (component is Components.NONE) + { + if(withLogging) + LOGGER.LogWarning("Assistant '{AssistantName}' is visible because no component is specified.", assistantName); + + return true; + } + + // Map Components enum to ConfigurableAssistant enum: + var configurableAssistant = component switch + { + Components.GRAMMAR_SPELLING_ASSISTANT => ConfigurableAssistant.GRAMMAR_SPELLING_ASSISTANT, + Components.ICON_FINDER_ASSISTANT => ConfigurableAssistant.ICON_FINDER_ASSISTANT, + Components.REWRITE_ASSISTANT => ConfigurableAssistant.REWRITE_ASSISTANT, + Components.TRANSLATION_ASSISTANT => ConfigurableAssistant.TRANSLATION_ASSISTANT, + Components.AGENDA_ASSISTANT => ConfigurableAssistant.AGENDA_ASSISTANT, + Components.CODING_ASSISTANT => ConfigurableAssistant.CODING_ASSISTANT, + Components.TEXT_SUMMARIZER_ASSISTANT => ConfigurableAssistant.TEXT_SUMMARIZER_ASSISTANT, + Components.EMAIL_ASSISTANT => ConfigurableAssistant.EMAIL_ASSISTANT, + Components.LEGAL_CHECK_ASSISTANT => ConfigurableAssistant.LEGAL_CHECK_ASSISTANT, + Components.SYNONYMS_ASSISTANT => ConfigurableAssistant.SYNONYMS_ASSISTANT, + Components.MY_TASKS_ASSISTANT => ConfigurableAssistant.MY_TASKS_ASSISTANT, + Components.JOB_POSTING_ASSISTANT => ConfigurableAssistant.JOB_POSTING_ASSISTANT, + Components.BIAS_DAY_ASSISTANT => ConfigurableAssistant.BIAS_DAY_ASSISTANT, + Components.ERI_ASSISTANT => ConfigurableAssistant.ERI_ASSISTANT, + Components.DOCUMENT_ANALYSIS_ASSISTANT => ConfigurableAssistant.DOCUMENT_ANALYSIS_ASSISTANT, + Components.I18N_ASSISTANT => ConfigurableAssistant.I18N_ASSISTANT, + + _ => ConfigurableAssistant.UNKNOWN, + }; + + // If the component doesn't map to a configurable assistant, it's always visible: + if (configurableAssistant is ConfigurableAssistant.UNKNOWN) + { + if(withLogging) + LOGGER.LogWarning("Assistant '{AssistantName}' is visible because its component '{Component}' does not map to a configurable assistant.", assistantName, component); + + return true; + } + + // Check if the assistant is hidden by any configuration plugin: + var isHidden = settingsManager.ConfigurationData.App.HiddenAssistants.Contains(configurableAssistant); + if (isHidden && withLogging) + LOGGER.LogInformation("Assistant '{AssistantName}' is hidden based on the configuration.", assistantName); + + return !isHidden; + } + + /// + /// Checks if any assistant in a category should be visible. + /// + /// The settings manager to check configuration against. + /// The name of the assistant category (for logging purposes). + /// The assistants in the category with their optional preview feature requirements. + /// True if at least one assistant in the category should be visible, false otherwise. + public static bool IsAnyCategoryAssistantVisible(this SettingsManager settingsManager, string categoryName, params (Components Component, PreviewFeatures RequiredPreviewFeature)[] assistants) + { + foreach (var (component, requiredPreviewFeature) in assistants) + if (settingsManager.IsAssistantVisible(component, withLogging: false, requiredPreviewFeature: requiredPreviewFeature)) + return true; + + LOGGER.LogInformation("No assistants in category '{CategoryName}' are visible.", categoryName); + return false; + } +}