mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-08-11 19:52:10 +00:00
Added an assistant category block which derives its heading from the visible assistants
This commit is contained in:
parent
6e143aafaa
commit
628be073b8
@ -9,7 +9,7 @@ using DialogOptions = AIStudio.Dialogs.DialogOptions;
|
|||||||
|
|
||||||
namespace AIStudio.Components;
|
namespace AIStudio.Components;
|
||||||
|
|
||||||
public partial class AssistantBlock<TSettings> : MSGComponentBase where TSettings : IComponent
|
public partial class AssistantBlock<TSettings> : MSGComponentBase, IAssistantCategoryMember where TSettings : IComponent
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Describes the assistant session indicator shown on top of the assistant icon.
|
/// Describes the assistant session indicator shown on top of the assistant icon.
|
||||||
@ -58,6 +58,12 @@ public partial class AssistantBlock<TSettings> : MSGComponentBase where TSetting
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public PreviewFeatures RequiredPreviewFeature { get; set; } = PreviewFeatures.NONE;
|
public PreviewFeatures RequiredPreviewFeature { get; set; } = PreviewFeatures.NONE;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the assistant category this block belongs to, if any.
|
||||||
|
/// </summary>
|
||||||
|
[CascadingParameter]
|
||||||
|
public AssistantCategoryBlock? Category { get; set; }
|
||||||
|
|
||||||
[Inject]
|
[Inject]
|
||||||
private MudTheme ColorTheme { get; init; } = null!;
|
private MudTheme ColorTheme { get; init; } = null!;
|
||||||
|
|
||||||
@ -88,7 +94,8 @@ public partial class AssistantBlock<TSettings> : MSGComponentBase where TSetting
|
|||||||
|
|
||||||
private string BlockStyle => $"border-width: 3px; border-color: {this.BorderColor}; border-radius: 12px; border-style: solid; max-width: 20em;";
|
private string BlockStyle => $"border-width: 3px; border-color: {this.BorderColor}; border-radius: 12px; border-style: solid; max-width: 20em;";
|
||||||
|
|
||||||
private bool IsVisible => this.SettingsManager.IsAssistantVisible(this.Component, assistantName: this.Name, requiredPreviewFeature: this.RequiredPreviewFeature);
|
/// <inheritdoc />
|
||||||
|
public bool IsVisible => this.SettingsManager.IsAssistantVisible(this.Component, assistantName: this.Name, requiredPreviewFeature: this.RequiredPreviewFeature);
|
||||||
|
|
||||||
private bool HasSettingsPanel => typeof(TSettings) != typeof(NoSettingsPanel);
|
private bool HasSettingsPanel => typeof(TSettings) != typeof(NoSettingsPanel);
|
||||||
|
|
||||||
@ -153,6 +160,7 @@ public partial class AssistantBlock<TSettings> : MSGComponentBase where TSetting
|
|||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
this.MediaTranscriptionService.StateChanged += this.OnMediaImportStateChanged;
|
this.MediaTranscriptionService.StateChanged += this.OnMediaImportStateChanged;
|
||||||
|
this.Category?.RegisterAssistant(this);
|
||||||
await base.OnInitializedAsync();
|
await base.OnInitializedAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,6 +173,7 @@ public partial class AssistantBlock<TSettings> : MSGComponentBase where TSetting
|
|||||||
protected override void DisposeResources()
|
protected override void DisposeResources()
|
||||||
{
|
{
|
||||||
this.MediaTranscriptionService.StateChanged -= this.OnMediaImportStateChanged;
|
this.MediaTranscriptionService.StateChanged -= this.OnMediaImportStateChanged;
|
||||||
|
this.Category?.UnregisterAssistant(this);
|
||||||
base.DisposeResources();
|
base.DisposeResources();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,11 @@
|
|||||||
|
@if (this.HasVisibleAssistant)
|
||||||
|
{
|
||||||
|
<MudText Typo="Typo.h4" Class="@this.HeaderClass">
|
||||||
|
@this.Title
|
||||||
|
</MudText>
|
||||||
|
}
|
||||||
|
<CascadingValue Value="this" IsFixed="@true">
|
||||||
|
<MudStack Row="@true" Wrap="@Wrap.Wrap" Class="@this.StackClass">
|
||||||
|
@this.ChildContent
|
||||||
|
</MudStack>
|
||||||
|
</CascadingValue>
|
||||||
@ -0,0 +1,70 @@
|
|||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
|
namespace AIStudio.Components;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Renders one category of assistants together with its heading.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// The heading is derived from the assistant blocks inside this category: it is rendered only when
|
||||||
|
/// at least one of them is visible. Thus, hiding assistants by configuration can never leave an
|
||||||
|
/// empty category heading behind.
|
||||||
|
/// </remarks>
|
||||||
|
public partial class AssistantCategoryBlock : ComponentBase
|
||||||
|
{
|
||||||
|
private readonly HashSet<IAssistantCategoryMember> members = [];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The heading of this category.
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public string Title { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The CSS classes used for the heading.
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public string HeaderClass { get; set; } = "mb-2 mr-3 mt-6";
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public RenderFragment? ChildContent { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds an assistant block to this category.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Assistant blocks call this while they initialize, i.e. after this category was rendered for
|
||||||
|
/// the first time. Hence, we have to render again to show the heading.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="member">The assistant block which belongs to this category.</param>
|
||||||
|
internal void RegisterAssistant(IAssistantCategoryMember member)
|
||||||
|
{
|
||||||
|
if (this.members.Add(member))
|
||||||
|
this.StateHasChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes an assistant block from this category.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="member">The assistant block which no longer belongs to this category.</param>
|
||||||
|
internal void UnregisterAssistant(IAssistantCategoryMember member) => this.members.Remove(member);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets whether at least one assistant of this category is visible right now.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// We evaluate this live instead of caching it. That way, changes to the configuration take
|
||||||
|
/// effect as soon as the assistants page renders again.
|
||||||
|
/// </remarks>
|
||||||
|
private bool HasVisibleAssistant => this.members.Any(member => member.IsVisible);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the CSS classes used for the assistant stack.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// The stack must be rendered even when no assistant is visible, because the assistant blocks
|
||||||
|
/// register themselves while rendering. Without any visible assistant, we drop the margin so
|
||||||
|
/// that a hidden category leaves no gap behind.
|
||||||
|
/// </remarks>
|
||||||
|
private string StackClass => this.HasVisibleAssistant ? "mb-3" : string.Empty;
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
namespace AIStudio.Components;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents an assistant block which belongs to an assistant category.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Assistant blocks are generic over their settings dialog. This interface gives the category block
|
||||||
|
/// access to their visibility without the need to know that type parameter.
|
||||||
|
/// </remarks>
|
||||||
|
public interface IAssistantCategoryMember
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets whether the assistant is visible right now.
|
||||||
|
/// </summary>
|
||||||
|
bool IsVisible { get; }
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user