Files
AI-Studio/app/MindWork AI Studio/Assistants/BeyondFactsLab/BeyondFactsLabAssistant.razor.cs
T

123 lines
4.5 KiB
C#

using AIStudio.Components;
using AIStudio.Dialogs.Settings;
using Microsoft.AspNetCore.Components;
using DialogOptions = AIStudio.Dialogs.DialogOptions;
namespace AIStudio.Assistants.BeyondFactsLab;
/// <summary>
/// The page of the BeyondFacts Lab, which guides researchers through the preparation of a challenging appearance.
/// </summary>
/// <remarks>
/// The lab keeps several preparations, each with steps of their own, so it does not inherit AssistantBase,
/// which knows one input and one result. Like the Visual Briefing assistant, it checks by itself whether it
/// may be opened.
/// </remarks>
public partial class BeyondFactsLabAssistant : MSGComponentBase
{
[Inject]
private IDialogService DialogService { get; init; } = null!;
[Inject]
private NavigationManager NavigationManager { get; init; } = null!;
[Inject]
private BeyondFactsLabStore Store { get; init; } = null!;
[Inject]
private BflConversationService ConversationService { get; init; } = null!;
[Inject]
private ILogger<BeyondFactsLabAssistant> Logger { get; init; } = null!;
[Inject]
private IJSRuntime JsRuntime { get; init; } = null!;
/// <summary>
/// Whether the person may open the lab, so that the page did not send them away.
/// </summary>
private bool mayOpen;
/// <summary>
/// The empty element right before the header of the preparation, which marks where the header sits in the flow.
/// </summary>
private ElementReference stickyHeaderAnchor;
/// <summary>
/// Whether the next render shows another step, which then starts at the top.
/// </summary>
private bool scrollToActiveStep;
/// <inheritdoc />
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
if (!BflAccess.CanOpen(this.SettingsManager, T("BeyondFacts Lab")))
{
this.NavigationManager.NavigateTo(Routes.ASSISTANTS);
return;
}
this.ApplyFilters([], [Event.CONFIGURATION_CHANGED]);
this.mayOpen = true;
await this.RunStoreActionAsync(() => this.ReloadProjectsAsync(null));
}
/// <inheritdoc />
protected override async Task OnAfterRenderAsync(bool firstRender)
{
await base.OnAfterRenderAsync(firstRender);
if (this.scrollToActiveStep)
{
// The person scrolled down in one step and chose another one; it starts right under the header:
this.scrollToActiveStep = false;
await this.stickyHeaderAnchor.ScrollToStickyHeaderAsync(this.JsRuntime);
}
if (firstRender && this.mayOpen)
await this.ShowNoticeIfNeededAsync();
}
/// <summary>
/// Shows the notes of the lab, unless the person confirmed them as they are now.
/// </summary>
private async Task ShowNoticeIfNeededAsync()
{
var notice = BflNotice.Text;
var currentHash = BflNotice.ComputeHash(notice);
if (BflNotice.IsAccepted(this.SettingsManager.ConfigurationData.BeyondFactsLab.AcceptedNoticeHash, currentHash))
return;
var parameters = new DialogParameters<BflNoticeDialog> { { dialog => dialog.Notice, notice } };
var reference = await this.DialogService.ShowAsync<BflNoticeDialog>(T("BeyondFacts Lab"), parameters, DialogOptions.BLOCKING_FULLSCREEN);
var result = await reference.Result;
if (result is null || result.Canceled)
return;
this.SettingsManager.ConfigurationData.BeyondFactsLab.AcceptedNoticeHash = currentHash;
await this.SettingsManager.StoreSettings();
}
/// <inheritdoc />
protected override async Task ProcessIncomingMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data) where T : default
{
if (triggeredEvent is Event.CONFIGURATION_CHANGED)
{
// An organization may hide the lab, or the person may switch its preview feature off, while the page is open:
if (!BflAccess.CanOpen(this.SettingsManager))
{
this.NavigationManager.NavigateTo(Routes.ASSISTANTS);
return;
}
// A changed option, such as the form of address in the options of the lab, shows right away:
this.StateHasChanged();
}
await base.ProcessIncomingMessage(sendingComponent, triggeredEvent, data);
}
private async Task OpenSettingsDialogAsync() => await this.DialogService.ShowAsync<SettingsDialogBeyondFactsLab>(null, new DialogParameters(), DialogOptions.FULLSCREEN);
}