Refactored visibility logic

This commit is contained in:
Thorsten Sommer 2026-01-12 19:44:51 +01:00
parent e9303b161b
commit 8eb3394bef
Signed by: tsommer
GPG Key ID: 371BBA77A02C0108
4 changed files with 124 additions and 141 deletions

View File

@ -1,30 +1,33 @@
@inherits MSGComponentBase
@typeparam TSettings
<MudCard Outlined="@true" Style="@this.BlockStyle">
<MudCardHeader>
<CardHeaderContent>
<MudStack AlignItems="AlignItems.Center" Row="@true">
<MudIcon Icon="@this.Icon" Size="Size.Large" Color="Color.Primary"/>
<MudText Typo="Typo.h6">
@this.Name
@if (this.IsVisible)
{
<MudCard Outlined="@true" Style="@this.BlockStyle">
<MudCardHeader>
<CardHeaderContent>
<MudStack AlignItems="AlignItems.Center" Row="@true">
<MudIcon Icon="@this.Icon" Size="Size.Large" Color="Color.Primary"/>
<MudText Typo="Typo.h6">
@this.Name
</MudText>
</MudStack>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent>
<MudStack>
<MudText>
@this.Description
</MudText>
</MudStack>
</CardHeaderContent>
</MudCardHeader>
<MudCardContent>
<MudStack>
<MudText>
@this.Description
</MudText>
</MudStack>
</MudCardContent>
<MudCardActions>
<MudButtonGroup Variant="Variant.Outlined">
<MudButton Size="Size.Large" Variant="Variant.Filled" StartIcon="@this.Icon" Color="Color.Default" Href="@this.Link">
@this.ButtonText
</MudButton>
<MudIconButton Variant="Variant.Text" Icon="@Icons.Material.Filled.Settings" Color="Color.Default" OnClick="@this.OpenSettingsDialog"/>
</MudButtonGroup>
</MudCardActions>
</MudCard>
</MudCardContent>
<MudCardActions>
<MudButtonGroup Variant="Variant.Outlined">
<MudButton Size="Size.Large" Variant="Variant.Filled" StartIcon="@this.Icon" Color="Color.Default" Href="@this.Link">
@this.ButtonText
</MudButton>
<MudIconButton Variant="Variant.Text" Icon="@Icons.Material.Filled.Settings" Color="Color.Default" OnClick="@this.OpenSettingsDialog"/>
</MudButtonGroup>
</MudCardActions>
</MudCard>
}

View File

@ -1,3 +1,6 @@
using AIStudio.Settings;
using AIStudio.Settings.DataModel;
using Microsoft.AspNetCore.Components;
using DialogOptions = AIStudio.Dialogs.DialogOptions;
@ -20,6 +23,12 @@ public partial class AssistantBlock<TSettings> : MSGComponentBase where TSetting
[Parameter]
public string Link { get; set; } = string.Empty;
[Parameter]
public Tools.Components Component { get; set; } = Tools.Components.NONE;
[Parameter]
public PreviewFeatures? RequiredPreviewFeature { get; set; }
[Inject]
private MudTheme ColorTheme { get; init; } = null!;
@ -27,6 +36,9 @@ public partial class AssistantBlock<TSettings> : MSGComponentBase where TSetting
[Inject]
private IDialogService DialogService { get; init; } = null!;
[Inject]
private ILogger<AssistantBlock<TSettings>> Logger { get; init; } = null!;
private async Task OpenSettingsDialog()
{
var dialogParameters = new DialogParameters();
@ -41,4 +53,71 @@ public partial class AssistantBlock<TSettings> : 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();
}
}
/// <summary>
/// Checks if an assistant should be visible based on configuration.
/// </summary>
/// <returns>True if the assistant should be visible, false otherwise.</returns>
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;
}
}

View File

@ -14,105 +14,46 @@
@T("General")
</MudText>
<MudStack Row="@true" Wrap="@Wrap.Wrap" Class="mb-3">
@if (this.IsAssistantVisible(Components.TEXT_SUMMARIZER_ASSISTANT))
{
<AssistantBlock TSettings="SettingsDialogTextSummarizer" Name="@T("Text Summarizer")" Description="@T("Use an LLM to summarize a given text.")" Icon="@Icons.Material.Filled.TextSnippet" Link="@Routes.ASSISTANT_SUMMARIZER"/>
}
@if (this.IsAssistantVisible(Components.TRANSLATION_ASSISTANT))
{
<AssistantBlock TSettings="SettingsDialogTranslation" Name="@T("Translation")" Description="@T("Translate text into another language.")" Icon="@Icons.Material.Filled.Translate" Link="@Routes.ASSISTANT_TRANSLATION"/>
}
@if (this.IsAssistantVisible(Components.GRAMMAR_SPELLING_ASSISTANT))
{
<AssistantBlock TSettings="SettingsDialogGrammarSpelling" Name="@T("Grammar & Spelling")" Description="@T("Check grammar and spelling of a given text.")" Icon="@Icons.Material.Filled.Edit" Link="@Routes.ASSISTANT_GRAMMAR_SPELLING"/>
}
@if (this.IsAssistantVisible(Components.REWRITE_ASSISTANT))
{
<AssistantBlock TSettings="SettingsDialogRewrite" Name="@T("Rewrite & Improve")" Description="@T("Rewrite and improve a given text for a chosen style.")" Icon="@Icons.Material.Filled.Edit" Link="@Routes.ASSISTANT_REWRITE"/>
}
@if (this.IsAssistantVisible(Components.SYNONYMS_ASSISTANT))
{
<AssistantBlock TSettings="SettingsDialogSynonyms" Name="@T("Synonyms")" Description="@T("Find synonyms for a given word or phrase.")" Icon="@Icons.Material.Filled.Spellcheck" Link="@Routes.ASSISTANT_SYNONYMS"/>
}
<AssistantBlock TSettings="SettingsDialogTextSummarizer" Component="Components.TEXT_SUMMARIZER_ASSISTANT" Name="@T("Text Summarizer")" Description="@T("Use an LLM to summarize a given text.")" Icon="@Icons.Material.Filled.TextSnippet" Link="@Routes.ASSISTANT_SUMMARIZER"/>
<AssistantBlock TSettings="SettingsDialogTranslation" Component="Components.TRANSLATION_ASSISTANT" Name="@T("Translation")" Description="@T("Translate text into another language.")" Icon="@Icons.Material.Filled.Translate" Link="@Routes.ASSISTANT_TRANSLATION"/>
<AssistantBlock TSettings="SettingsDialogGrammarSpelling" Component="Components.GRAMMAR_SPELLING_ASSISTANT" Name="@T("Grammar & Spelling")" Description="@T("Check grammar and spelling of a given text.")" Icon="@Icons.Material.Filled.Edit" Link="@Routes.ASSISTANT_GRAMMAR_SPELLING"/>
<AssistantBlock TSettings="SettingsDialogRewrite" Component="Components.REWRITE_ASSISTANT" Name="@T("Rewrite & Improve")" Description="@T("Rewrite and improve a given text for a chosen style.")" Icon="@Icons.Material.Filled.Edit" Link="@Routes.ASSISTANT_REWRITE"/>
<AssistantBlock TSettings="SettingsDialogSynonyms" Component="Components.SYNONYMS_ASSISTANT" Name="@T("Synonyms")" Description="@T("Find synonyms for a given word or phrase.")" Icon="@Icons.Material.Filled.Spellcheck" Link="@Routes.ASSISTANT_SYNONYMS"/>
</MudStack>
<MudText Typo="Typo.h4" Class="mb-2 mr-3 mt-6">
@T("Business")
</MudText>
<MudStack Row="@true" Wrap="@Wrap.Wrap" Class="mb-3">
@if (this.IsAssistantVisible(Components.EMAIL_ASSISTANT))
{
<AssistantBlock TSettings="SettingsDialogWritingEMails" Name="@T("E-Mail")" Description="@T("Generate an e-mail for a given context.")" Icon="@Icons.Material.Filled.Email" Link="@Routes.ASSISTANT_EMAIL"/>
}
@if (PreviewFeatures.PRE_DOCUMENT_ANALYSIS_2025.IsEnabled(this.SettingsManager) && this.IsAssistantVisible(Components.DOCUMENT_ANALYSIS_ASSISTANT))
{
<AssistantBlock TSettings="SettingsDialogDocumentAnalysis" Name="@T("Document Analysis")" Description="@T("Analyze a document regarding defined rules and extract key information.")" Icon="@Icons.Material.Filled.DocumentScanner" Link="@Routes.ASSISTANT_DOCUMENT_ANALYSIS"/>
}
@if (this.IsAssistantVisible(Components.MY_TASKS_ASSISTANT))
{
<AssistantBlock TSettings="SettingsDialogMyTasks" Name="@T("My Tasks")" Description="@T("Analyze a text or an email for tasks you need to complete.")" Icon="@Icons.Material.Filled.Task" Link="@Routes.ASSISTANT_MY_TASKS"/>
}
@if (this.IsAssistantVisible(Components.AGENDA_ASSISTANT))
{
<AssistantBlock TSettings="SettingsDialogAgenda" Name="@T("Agenda Planner")" Description="@T("Generate an agenda for a given meeting, seminar, etc.")" Icon="@Icons.Material.Filled.CalendarToday" Link="@Routes.ASSISTANT_AGENDA"/>
}
@if (this.IsAssistantVisible(Components.JOB_POSTING_ASSISTANT))
{
<AssistantBlock TSettings="SettingsDialogJobPostings" Name="@T("Job Posting")" Description="@T("Generate a job posting for a given job description.")" Icon="@Icons.Material.Filled.Work" Link="@Routes.ASSISTANT_JOB_POSTING"/>
}
@if (this.IsAssistantVisible(Components.LEGAL_CHECK_ASSISTANT))
{
<AssistantBlock TSettings="SettingsDialogLegalCheck" Name="@T("Legal Check")" Description="@T("Ask a question about a legal document.")" Icon="@Icons.Material.Filled.Gavel" Link="@Routes.ASSISTANT_LEGAL_CHECK"/>
}
@if (this.IsAssistantVisible(Components.ICON_FINDER_ASSISTANT))
{
<AssistantBlock TSettings="SettingsDialogIconFinder" Name="@T("Icon Finder")" Description="@T("Use an LLM to find an icon for a given context.")" Icon="@Icons.Material.Filled.FindInPage" Link="@Routes.ASSISTANT_ICON_FINDER"/>
}
<AssistantBlock TSettings="SettingsDialogWritingEMails" Component="Components.EMAIL_ASSISTANT" Name="@T("E-Mail")" Description="@T("Generate an e-mail for a given context.")" Icon="@Icons.Material.Filled.Email" Link="@Routes.ASSISTANT_EMAIL"/>
<AssistantBlock TSettings="SettingsDialogDocumentAnalysis" Component="Components.DOCUMENT_ANALYSIS_ASSISTANT" RequiredPreviewFeature="PreviewFeatures.PRE_DOCUMENT_ANALYSIS_2025" Name="@T("Document Analysis")" Description="@T("Analyze a document regarding defined rules and extract key information.")" Icon="@Icons.Material.Filled.DocumentScanner" Link="@Routes.ASSISTANT_DOCUMENT_ANALYSIS"/>
<AssistantBlock TSettings="SettingsDialogMyTasks" Component="Components.MY_TASKS_ASSISTANT" Name="@T("My Tasks")" Description="@T("Analyze a text or an email for tasks you need to complete.")" Icon="@Icons.Material.Filled.Task" Link="@Routes.ASSISTANT_MY_TASKS"/>
<AssistantBlock TSettings="SettingsDialogAgenda" Component="Components.AGENDA_ASSISTANT" Name="@T("Agenda Planner")" Description="@T("Generate an agenda for a given meeting, seminar, etc.")" Icon="@Icons.Material.Filled.CalendarToday" Link="@Routes.ASSISTANT_AGENDA"/>
<AssistantBlock TSettings="SettingsDialogJobPostings" Component="Components.JOB_POSTING_ASSISTANT" Name="@T("Job Posting")" Description="@T("Generate a job posting for a given job description.")" Icon="@Icons.Material.Filled.Work" Link="@Routes.ASSISTANT_JOB_POSTING"/>
<AssistantBlock TSettings="SettingsDialogLegalCheck" Component="Components.LEGAL_CHECK_ASSISTANT" Name="@T("Legal Check")" Description="@T("Ask a question about a legal document.")" Icon="@Icons.Material.Filled.Gavel" Link="@Routes.ASSISTANT_LEGAL_CHECK"/>
<AssistantBlock TSettings="SettingsDialogIconFinder" Component="Components.ICON_FINDER_ASSISTANT" Name="@T("Icon Finder")" Description="@T("Use an LLM to find an icon for a given context.")" Icon="@Icons.Material.Filled.FindInPage" Link="@Routes.ASSISTANT_ICON_FINDER"/>
</MudStack>
<MudText Typo="Typo.h4" Class="mb-2 mr-3 mt-6">
@T("Learning")
</MudText>
<MudStack Row="@true" Wrap="@Wrap.Wrap" Class="mb-3">
@if (this.IsAssistantVisible(Components.BIAS_DAY_ASSISTANT))
{
<AssistantBlock TSettings="SettingsDialogAssistantBias" Name="@T("Bias of the Day")" Description="@T("Learn about one cognitive bias every day.")" Icon="@Icons.Material.Filled.Psychology" Link="@Routes.ASSISTANT_BIAS"/>
}
<AssistantBlock TSettings="SettingsDialogAssistantBias" Component="Components.BIAS_DAY_ASSISTANT" Name="@T("Bias of the Day")" Description="@T("Learn about one cognitive bias every day.")" Icon="@Icons.Material.Filled.Psychology" Link="@Routes.ASSISTANT_BIAS"/>
</MudStack>
<MudText Typo="Typo.h4" Class="mb-2 mr-3 mt-6">
@T("Software Engineering")
</MudText>
<MudStack Row="@true" Wrap="@Wrap.Wrap" Class="mb-3">
@if (this.IsAssistantVisible(Components.CODING_ASSISTANT))
{
<AssistantBlock TSettings="SettingsDialogCoding" Name="@T("Coding")" Description="@T("Get coding and debugging support from an LLM.")" Icon="@Icons.Material.Filled.Code" Link="@Routes.ASSISTANT_CODING"/>
}
@if (PreviewFeatures.PRE_RAG_2024.IsEnabled(this.SettingsManager) && this.IsAssistantVisible(Components.ERI_ASSISTANT))
{
<AssistantBlock TSettings="SettingsDialogERIServer" Name="@T("ERI Server")" Description="@T("Generate an ERI server to integrate business systems.")" Icon="@Icons.Material.Filled.PrivateConnectivity" Link="@Routes.ASSISTANT_ERI"/>
}
<AssistantBlock TSettings="SettingsDialogCoding" Component="Components.CODING_ASSISTANT" Name="@T("Coding")" Description="@T("Get coding and debugging support from an LLM.")" Icon="@Icons.Material.Filled.Code" Link="@Routes.ASSISTANT_CODING"/>
<AssistantBlock TSettings="SettingsDialogERIServer" Component="Components.ERI_ASSISTANT" RequiredPreviewFeature="PreviewFeatures.PRE_RAG_2024" Name="@T("ERI Server")" Description="@T("Generate an ERI server to integrate business systems.")" Icon="@Icons.Material.Filled.PrivateConnectivity" Link="@Routes.ASSISTANT_ERI"/>
</MudStack>
<MudText Typo="Typo.h4" Class="mb-2 mr-3 mt-6">
@T("AI Studio Development")
</MudText>
<MudStack Row="@true" Wrap="@Wrap.Wrap" Class="mb-3">
@if (this.IsAssistantVisible(Components.I18N_ASSISTANT))
{
<AssistantBlock TSettings="SettingsDialogI18N" Name="@T("Localization")" Description="@T("Translate AI Studio text content into other languages")" Icon="@Icons.Material.Filled.Translate" Link="@Routes.ASSISTANT_AI_STUDIO_I18N"/>
}
<AssistantBlock TSettings="SettingsDialogI18N" Component="Components.I18N_ASSISTANT" Name="@T("Localization")" Description="@T("Translate AI Studio text content into other languages")" Icon="@Icons.Material.Filled.Translate" Link="@Routes.ASSISTANT_AI_STUDIO_I18N"/>
</MudStack>
</InnerScrolling>

View File

@ -1,45 +1,5 @@
using AIStudio.Components;
using AIStudio.Settings;
namespace AIStudio.Pages;
public partial class Assistants : MSGComponentBase
{
/// <summary>
/// Checks if an assistant should be visible based on configuration.
/// </summary>
/// <param name="component">The assistant component to check.</param>
/// <returns>True if the assistant should be visible, false otherwise.</returns>
private bool IsAssistantVisible(Tools.Components component)
{
// Map Components enum to ConfigurableAssistant enum:
var configurableAssistant = 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)
return true;
// Check if the assistant is hidden by any configuration plugin:
return !this.SettingsManager.ConfigurationData.App.HiddenAssistants.Contains(configurableAssistant);
}
}
public partial class Assistants : MSGComponentBase;