Compare commits

..
11 Commits
60 changed files with 1628 additions and 891 deletions

No files matched your search

@@ -15,22 +15,8 @@
@this.Body @this.Body
} }
</MudForm> </MudForm>
<Issues IssuesData="@this.inputIssues"/>
@if (this.inputIssues.Any())
{
<MudPaper Class="pr-2 mt-3" Outlined="@true">
<MudText Typo="Typo.h6">Issues</MudText>
<MudList T="string">
@foreach (var issue in this.inputIssues)
{
<MudListItem Icon="@Icons.Material.Filled.Error" IconColor="Color.Error">
@issue
</MudListItem>
}
</MudList>
</MudPaper>
}
@if (this.resultingContentBlock is not null) @if (this.resultingContentBlock is not null)
{ {
<ContentBlockComponent Role="@this.resultingContentBlock.Role" Type="@this.resultingContentBlock.ContentType" Time="@this.resultingContentBlock.Time" Content="@this.resultingContentBlock.Content" Class="mr-2"/> <ContentBlockComponent Role="@this.resultingContentBlock.Role" Type="@this.resultingContentBlock.ContentType" Time="@this.resultingContentBlock.Time" Content="@this.resultingContentBlock.Content" Class="mr-2"/>
@@ -13,6 +13,8 @@ public partial class Changelog
public static readonly Log[] LOGS = public static readonly Log[] LOGS =
[ [
new (167, "v0.8.5, build 167 (2024-07-28 16:44 UTC)", "v0.8.5.md"),
new (166, "v0.8.4, build 166 (2024-07-26 06:53 UTC)", "v0.8.4.md"),
new (165, "v0.8.3, build 165 (2024-07-25 13:25 UTC)", "v0.8.3.md"), new (165, "v0.8.3, build 165 (2024-07-25 13:25 UTC)", "v0.8.3.md"),
new (164, "v0.8.2, build 164 (2024-07-16 18:03 UTC)", "v0.8.2.md"), new (164, "v0.8.2, build 164 (2024-07-16 18:03 UTC)", "v0.8.2.md"),
new (163, "v0.8.1, build 163 (2024-07-16 08:32 UTC)", "v0.8.1.md"), new (163, "v0.8.1, build 163 (2024-07-16 08:32 UTC)", "v0.8.1.md"),
@@ -0,0 +1,7 @@
@inherits ConfigurationBase
<MudField Disabled="@this.Disabled()" Label="@this.OptionDescription" Variant="Variant.Outlined" HelperText="@this.OptionHelp" Class="@MARGIN_CLASS">
<MudSwitch T="bool" Disabled="@this.Disabled()" Value="@this.State()" ValueChanged="@this.OptionChanged" Color="Color.Primary">
@(this.State() ? this.LabelOn : this.LabelOff)
</MudSwitch>
</MudField>
@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
namespace AIStudio.Components; namespace AIStudio.Components.Blocks;
/// <summary> /// <summary>
/// Configuration component for any boolean option. /// Configuration component for any boolean option.
@@ -0,0 +1 @@
<ConfigurationSelect OptionDescription="Preselected provider" Disabled="@this.Disabled" OptionHelp="Select a provider that is preselected." Data="@this.Data" SelectedValue="@this.SelectedValue" SelectionUpdate="@this.SelectionUpdate"/>
@@ -0,0 +1,83 @@
using AIStudio.Settings;
using AIStudio.Tools;
using Microsoft.AspNetCore.Components;
namespace AIStudio.Components.Blocks;
public partial class ConfigurationProviderSelection : ComponentBase, IMessageBusReceiver, IDisposable
{
[Parameter]
public Func<string> SelectedValue { get; set; } = () => string.Empty;
[Parameter]
public Action<string> SelectionUpdate { get; set; } = _ => { };
[Parameter]
public IEnumerable<ConfigurationSelectData<string>> Data { get; set; } = new List<ConfigurationSelectData<string>>();
/// <summary>
/// Is the selection component disabled?
/// </summary>
[Parameter]
public Func<bool> Disabled { get; set; } = () => false;
[Inject]
private SettingsManager SettingsManager { get; init; } = null!;
[Inject]
private MessageBus MessageBus { get; init; } = null!;
#region Overrides of ComponentBase
protected override async Task OnParametersSetAsync()
{
// Register this component with the message bus:
this.MessageBus.RegisterComponent(this);
this.MessageBus.ApplyFilters(this, [], [ Event.CONFIGURATION_CHANGED ]);
await base.OnParametersSetAsync();
}
#endregion
#region Implementation of IMessageBusReceiver
public async Task ProcessMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data)
{
switch (triggeredEvent)
{
case Event.CONFIGURATION_CHANGED:
if(string.IsNullOrWhiteSpace(this.SelectedValue()))
break;
// Check if the selected value is still valid:
if (this.Data.All(x => x.Value != this.SelectedValue()))
{
this.SelectedValue = () => string.Empty;
this.SelectionUpdate(string.Empty);
await this.SettingsManager.StoreSettings();
}
this.StateHasChanged();
break;
}
}
public Task<TResult?> ProcessMessageWithResult<TPayload, TResult>(ComponentBase? sendingComponent, Event triggeredEvent, TPayload? data)
{
return Task.FromResult<TResult?>(default);
}
#endregion
#region Implementation of IDisposable
public void Dispose()
{
this.MessageBus.Unregister(this);
}
#endregion
}
@@ -0,0 +1,11 @@
@inherits ConfigurationBase
@typeparam T
<MudSelect T="T" Value="@this.SelectedValue()" Strict="@true" Disabled="@this.Disabled()" Margin="Margin.Dense" Label="@this.OptionDescription" Class="@GetClass" Variant="Variant.Outlined" HelperText="@this.OptionHelp" ValueChanged="@this.OptionChanged">
@foreach (var data in this.Data)
{
<MudSelectItem Value="@data.Value">
@data.Name
</MudSelectItem>
}
</MudSelect>
@@ -1,6 +1,8 @@
using AIStudio.Settings;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
namespace AIStudio.Components; namespace AIStudio.Components.Blocks;
/// <summary> /// <summary>
/// Configuration component for selecting a value from a list. /// Configuration component for selecting a value from a list.
@@ -0,0 +1,8 @@
@typeparam T
@inherits ConfigurationBase
<MudField Label="@this.OptionDescription" Variant="Variant.Outlined" Class="mb-3" Disabled="@this.Disabled()">
<MudSlider T="@T" Size="Size.Medium" Value="@this.Value()" ValueChanged="@this.OptionChanged" Min="@this.Min" Max="@this.Max" Step="@this.Step" Immediate="@true" Disabled="@this.Disabled()">
@this.Value() @this.Unit
</MudSlider>
</MudField>
@@ -0,0 +1,51 @@
using System.Numerics;
using Microsoft.AspNetCore.Components;
namespace AIStudio.Components.Blocks;
public partial class ConfigurationSlider<T> : ConfigurationBase where T : struct, INumber<T>
{
/// <summary>
/// The minimum value for the slider.
/// </summary>
[Parameter]
public T Min { get; set; } = T.Zero;
/// <summary>
/// The maximum value for the slider.
/// </summary>
[Parameter]
public T Max { get; set; } = T.One;
/// <summary>
/// The step size for the slider.
/// </summary>
[Parameter]
public T Step { get; set; } = T.One;
/// <summary>
/// The unit to display next to the slider's value.
/// </summary>
[Parameter]
public string Unit { get; set; } = string.Empty;
/// <summary>
/// The value used for the slider.
/// </summary>
[Parameter]
public Func<T> Value { get; set; } = () => T.Zero;
/// <summary>
/// An action which is called when the option is changed.
/// </summary>
[Parameter]
public Action<T> ValueUpdate { get; set; } = _ => { };
private async Task OptionChanged(T updatedValue)
{
this.ValueUpdate(updatedValue);
await this.SettingsManager.StoreSettings();
await this.InformAboutChange();
}
}
@@ -0,0 +1,18 @@
@inherits ConfigurationBase
<MudTextField
T="string"
Text="@this.Text()"
TextChanged="@this.OptionChanged"
Label="@this.OptionDescription"
Disabled="@this.Disabled()"
Class="mb-3"
Adornment="Adornment.Start"
AdornmentIcon="@this.Icon"
AdornmentColor="@this.IconColor"
UserAttributes="@SPELLCHECK_ATTRIBUTES"
Lines="1"
Immediate="@false"
DebounceInterval="500"
Variant="Variant.Outlined"
/>
@@ -0,0 +1,37 @@
using Microsoft.AspNetCore.Components;
namespace AIStudio.Components.Blocks;
public partial class ConfigurationText : ConfigurationBase
{
/// <summary>
/// The text used for the textfield.
/// </summary>
[Parameter]
public Func<string> Text { get; set; } = () => string.Empty;
/// <summary>
/// An action which is called when the option is changed.
/// </summary>
[Parameter]
public Action<string> TextUpdate { get; set; } = _ => { };
/// <summary>
/// The icon to display next to the textfield.
/// </summary>
[Parameter]
public string Icon { get; set; } = Icons.Material.Filled.Info;
/// <summary>
/// The color of the icon to use.
/// </summary>
[Parameter]
public Color IconColor { get; set; } = Color.Default;
private async Task OptionChanged(string updatedText)
{
this.TextUpdate(updatedText);
await this.SettingsManager.StoreSettings();
await this.InformAboutChange();
}
}
@@ -0,0 +1,14 @@
@if (this.IssuesData.Any())
{
<MudPaper Class="pa-3 mr-3 mt-3 border-dashed border rounded-lg mud-alert-outlined-error">
<MudText Typo="Typo.h6">Issues</MudText>
<MudList T="string">
@foreach (var issue in this.IssuesData)
{
<MudListItem Icon="@Icons.Material.Filled.Error" IconColor="Color.Error">
@issue
</MudListItem>
}
</MudList>
</MudPaper>
}
@@ -0,0 +1,9 @@
using Microsoft.AspNetCore.Components;
namespace AIStudio.Components.Blocks;
public partial class Issues : ComponentBase
{
[Parameter]
public IEnumerable<string> IssuesData { get; set; } = [];
}
@@ -1,7 +1,7 @@
<MudDialog> <MudDialog>
<DialogContent> <DialogContent>
<MudText Typo="Typo.body1">@this.Message</MudText> <MudText Typo="Typo.body1">@this.Message</MudText>
<MudTextField T="string" @bind-Text="@this.UserInput" Variant="Variant.Outlined" AutoGrow="@false" Lines="1" Label="Chat name" AutoFocus="@true"/> <MudTextField T="string" @bind-Text="@this.UserInput" Variant="Variant.Outlined" AutoGrow="@false" Lines="1" Label="Chat name" AutoFocus="@true" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
</DialogContent> </DialogContent>
<DialogActions> <DialogActions>
<MudButton OnClick="@this.Cancel" Variant="Variant.Filled">Cancel</MudButton> <MudButton OnClick="@this.Cancel" Variant="Variant.Filled">Cancel</MudButton>
@@ -1,3 +1,5 @@
using AIStudio.Settings;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
namespace AIStudio.Components.CommonDialogs; namespace AIStudio.Components.CommonDialogs;
@@ -18,6 +20,22 @@ public partial class SingleInputDialog : ComponentBase
[Parameter] [Parameter]
public Color ConfirmColor { get; set; } = Color.Error; public Color ConfirmColor { get; set; } = Color.Error;
[Inject]
private SettingsManager SettingsManager { get; set; } = null!;
private static readonly Dictionary<string, object?> USER_INPUT_ATTRIBUTES = new();
#region Overrides of ComponentBase
protected override async Task OnInitializedAsync()
{
// Configure the spellchecking for the user input:
this.SettingsManager.InjectSpellchecking(USER_INPUT_ATTRIBUTES);
await base.OnInitializedAsync();
}
#endregion
private void Cancel() => this.MudDialog.Cancel(); private void Cancel() => this.MudDialog.Cancel();
@@ -1,7 +1,7 @@
<MudDialog> <MudDialog>
<DialogContent> <DialogContent>
<MudText Typo="Typo.body1">@this.Message</MudText> <MudText Typo="Typo.body1">@this.Message</MudText>
<MudList Clickable="@true" @bind-SelectedValue="@this.selectedWorkspace"> <MudList T="Guid" @bind-SelectedValue="@this.selectedWorkspace">
@foreach (var (workspaceName, workspaceId) in this.workspaces) @foreach (var (workspaceName, workspaceId) in this.workspaces)
{ {
<MudListItem Text="@workspaceName" Icon="@Icons.Material.Filled.Description" Value="@workspaceId" /> <MudListItem Text="@workspaceName" Icon="@Icons.Material.Filled.Description" Value="@workspaceId" />
@@ -21,7 +21,7 @@ public partial class WorkspaceSelectionDialog : ComponentBase
public string ConfirmText { get; set; } = "OK"; public string ConfirmText { get; set; } = "OK";
private readonly Dictionary<string, Guid> workspaces = new(); private readonly Dictionary<string, Guid> workspaces = new();
private object? selectedWorkspace; private Guid selectedWorkspace;
#region Overrides of ComponentBase #region Overrides of ComponentBase
@@ -56,5 +56,5 @@ public partial class WorkspaceSelectionDialog : ComponentBase
private void Cancel() => this.MudDialog.Cancel(); private void Cancel() => this.MudDialog.Cancel();
private void Confirm() => this.MudDialog.Close(DialogResult.Ok(this.selectedWorkspace is Guid workspaceId ? workspaceId : default)); private void Confirm() => this.MudDialog.Close(DialogResult.Ok(this.selectedWorkspace));
} }
@@ -8,7 +8,7 @@ namespace AIStudio.Components;
/// <summary> /// <summary>
/// A base class for configuration options. /// A base class for configuration options.
/// </summary> /// </summary>
public partial class ConfigurationBase : ComponentBase public partial class ConfigurationBase : ComponentBase, IMessageBusReceiver, IDisposable
{ {
/// <summary> /// <summary>
/// The description of the option, i.e., the name. Should be /// The description of the option, i.e., the name. Should be
@@ -23,6 +23,12 @@ public partial class ConfigurationBase : ComponentBase
[Parameter] [Parameter]
public string OptionHelp { get; set; } = string.Empty; public string OptionHelp { get; set; } = string.Empty;
/// <summary>
/// Is the option disabled?
/// </summary>
[Parameter]
public Func<bool> Disabled { get; set; } = () => false;
[Inject] [Inject]
protected SettingsManager SettingsManager { get; init; } = null!; protected SettingsManager SettingsManager { get; init; } = null!;
@@ -30,6 +36,53 @@ public partial class ConfigurationBase : ComponentBase
protected MessageBus MessageBus { get; init; } = null!; protected MessageBus MessageBus { get; init; } = null!;
protected const string MARGIN_CLASS = "mb-6"; protected const string MARGIN_CLASS = "mb-6";
protected static readonly Dictionary<string, object?> SPELLCHECK_ATTRIBUTES = new();
#region Overrides of ComponentBase
protected override async Task OnInitializedAsync()
{
// Configure the spellchecking for the instance name input:
this.SettingsManager.InjectSpellchecking(SPELLCHECK_ATTRIBUTES);
// Register this component with the message bus:
this.MessageBus.RegisterComponent(this);
this.MessageBus.ApplyFilters(this, [], [ Event.CONFIGURATION_CHANGED ]);
await base.OnInitializedAsync();
}
#endregion
protected async Task InformAboutChange() => await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED); protected async Task InformAboutChange() => await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
#region Implementation of IMessageBusReceiver
public Task ProcessMessage<TMsg>(ComponentBase? sendingComponent, Event triggeredEvent, TMsg? data)
{
switch (triggeredEvent)
{
case Event.CONFIGURATION_CHANGED:
this.StateHasChanged();
break;
}
return Task.CompletedTask;
}
public Task<TResult?> ProcessMessageWithResult<TPayload, TResult>(ComponentBase? sendingComponent, Event triggeredEvent, TPayload? data)
{
return Task.FromResult<TResult?>(default);
}
#endregion
#region Implementation of IDisposable
public void Dispose()
{
this.MessageBus.Unregister(this);
}
#endregion
} }
@@ -1,7 +0,0 @@
@inherits ConfigurationBase
<MudField Label="@this.OptionDescription" Variant="Variant.Outlined" HelperText="@this.OptionHelp" Class="@MARGIN_CLASS">
<MudSwitch T="bool" Value="@this.State()" ValueChanged="@(updatedState => this.OptionChanged(updatedState))">
@(this.State() ? this.LabelOn : this.LabelOff)
</MudSwitch>
</MudField>
@@ -1,11 +0,0 @@
@inherits ConfigurationBase
@typeparam T
<MudSelect T="T" Value="@this.SelectedValue()" Margin="Margin.Dense" Label="@this.OptionDescription" Class="@GetClass" Variant="Variant.Outlined" HelperText="@this.OptionHelp" ValueChanged="selectedValue => this.OptionChanged(selectedValue)">
@foreach (var data in this.Data)
{
<MudSelectItem Value="@data.Value">
@data.Name
</MudSelectItem>
}
</MudSelect>
@@ -1,7 +0,0 @@
@inherits ConfigurationBase
<MudField Label="@this.OptionDescription" Variant="Variant.Outlined" HelperText="@this.OptionHelp" Class="@MARGIN_CLASS">
<MudButton Variant="Variant.Filled" StartIcon="@this.TriggerIcon" OnClick="@this.Click">
@this.TriggerText
</MudButton>
</MudField>
@@ -1,24 +0,0 @@
using Microsoft.AspNetCore.Components;
namespace AIStudio.Components;
public partial class ConfigurationTrigger : ConfigurationBase
{
[Parameter]
public string TriggerText { get; set; } = string.Empty;
[Parameter]
public string TriggerIcon { get; set; } = Icons.Material.Filled.AddBox;
[Parameter]
public Action OnClickSync { get; set; } = () => { };
[Parameter]
public Func<Task> OnClickAsync { get; set; } = () => Task.CompletedTask;
private async Task Click()
{
this.OnClickSync();
await this.OnClickAsync();
}
}
@@ -1,4 +1,4 @@
@using AIStudio.Settings @using AIStudio.Settings.DataModel
@inherits LayoutComponentBase @inherits LayoutComponentBase
<MudPaper Height="calc(100vh);" Elevation="0"> <MudPaper Height="calc(100vh);" Elevation="0">
@@ -1,5 +1,6 @@
using AIStudio.Components.CommonDialogs; using AIStudio.Components.CommonDialogs;
using AIStudio.Settings; using AIStudio.Settings;
using AIStudio.Settings.DataModel;
using AIStudio.Tools; using AIStudio.Tools;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
@@ -9,7 +10,7 @@ using DialogOptions = AIStudio.Components.CommonDialogs.DialogOptions;
namespace AIStudio.Components.Layout; namespace AIStudio.Components.Layout;
public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, IDisposable
{ {
[Inject] [Inject]
private IJSRuntime JsRuntime { get; init; } = null!; private IJSRuntime JsRuntime { get; init; } = null!;
@@ -211,4 +212,13 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver
await MessageBus.INSTANCE.SendMessage<bool>(this, Event.RESET_CHAT_STATE); await MessageBus.INSTANCE.SendMessage<bool>(this, Event.RESET_CHAT_STATE);
} }
} }
#region Implementation of IDisposable
public void Dispose()
{
this.MessageBus.Unregister(this);
}
#endregion
} }
@@ -9,7 +9,7 @@
<MudText> <MudText>
The following list shows the versions of the MindWork AI Studio, the used compilers, build time, etc.: The following list shows the versions of the MindWork AI Studio, the used compilers, build time, etc.:
</MudText> </MudText>
<MudList T="string"> <MudList T="string" Class="mb-3">
<MudListItem T="string" Icon="@Icons.Material.Outlined.Chat" Text="@VersionApp"/> <MudListItem T="string" Icon="@Icons.Material.Outlined.Chat" Text="@VersionApp"/>
<MudListItem T="string" Icon="@Icons.Material.Outlined.Timer" Text="@BuildTime"/> <MudListItem T="string" Icon="@Icons.Material.Outlined.Timer" Text="@BuildTime"/>
<MudListItem T="string" Icon="@Icons.Material.Outlined.Build" Text="@VersionDotnetSdk"/> <MudListItem T="string" Icon="@Icons.Material.Outlined.Build" Text="@VersionDotnetSdk"/>
@@ -7,6 +7,6 @@
<MudGrid> <MudGrid>
<AssistantBlock Name="Icon Finder" Description="Using a LLM to find an icon for a given context." Icon="@Icons.Material.Filled.FindInPage" Link="/assistant/icons"/> <AssistantBlock Name="Icon Finder" Description="Using a LLM to find an icon for a given context." Icon="@Icons.Material.Filled.FindInPage" Link="/assistant/icons"/>
<AssistantBlock Name="Text Summarizer" Description="Using a LLM to summarize a given text." Icon="@Icons.Material.Filled.TextSnippet" Link="/assistant/summarizer"/> <AssistantBlock Name="Text Summarizer" Description="Using a LLM to summarize a given text." Icon="@Icons.Material.Filled.TextSnippet" Link="/assistant/summarizer"/>
<AssistantBlock Name="Translator" Description="Translate text into another language." Icon="@Icons.Material.Filled.Translate" Link="/assistant/translator"/> <AssistantBlock Name="Translation" Description="Translate text into another language." Icon="@Icons.Material.Filled.Translate" Link="/assistant/translation"/>
<AssistantBlock Name="Coding" Description="Get coding and debugging support from a LLM." Icon="@Icons.Material.Filled.Code" Link="/assistant/coding"/> <AssistantBlock Name="Coding" Description="Get coding and debugging support from a LLM." Icon="@Icons.Material.Filled.Code" Link="/assistant/coding"/>
</MudGrid> </MudGrid>
@@ -1,6 +1,7 @@
@page "/chat" @page "/chat"
@using AIStudio.Chat @using AIStudio.Chat
@using AIStudio.Settings @using AIStudio.Settings
@using AIStudio.Settings.DataModel
@inherits MSGComponentBase @inherits MSGComponentBase
@@ -72,7 +73,7 @@
@if (this.SettingsManager.ConfigurationData.WorkspaceStorageBehavior is not WorkspaceStorageBehavior.DISABLE_WORKSPACES) @if (this.SettingsManager.ConfigurationData.WorkspaceStorageBehavior is not WorkspaceStorageBehavior.DISABLE_WORKSPACES)
{ {
<MudTooltip Text="Move chat to (another) workspace" Placement="@TOOLBAR_TOOLTIP_PLACEMENT"> <MudTooltip Text="Move the chat to a workspace, or to another if it is already in one." Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
<MudIconButton Icon="@Icons.Material.Filled.MoveToInbox" Disabled="@(!this.CanThreadBeSaved)" OnClick="() => this.MoveChatToWorkspace()"/> <MudIconButton Icon="@Icons.Material.Filled.MoveToInbox" Disabled="@(!this.CanThreadBeSaved)" OnClick="() => this.MoveChatToWorkspace()"/>
</MudTooltip> </MudTooltip>
} }
@@ -3,6 +3,7 @@ using AIStudio.Components.Blocks;
using AIStudio.Components.CommonDialogs; using AIStudio.Components.CommonDialogs;
using AIStudio.Provider; using AIStudio.Provider;
using AIStudio.Settings; using AIStudio.Settings;
using AIStudio.Settings.DataModel;
using AIStudio.Tools; using AIStudio.Tools;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
@@ -16,7 +16,7 @@
</MudButton> </MudButton>
<MudStack Row="@false" Class="mb-3"> <MudStack Row="@false" Class="mb-3">
<MudSwitch T="bool" @bind-Value="@this.provideCompilerMessages"> <MudSwitch T="bool" @bind-Value="@this.provideCompilerMessages" Color="Color.Primary">
@(this.provideCompilerMessages ? "Provide compiler messages" : "Provide no compiler messages") @(this.provideCompilerMessages ? "Provide compiler messages" : "Provide no compiler messages")
</MudSwitch> </MudSwitch>
@if (this.provideCompilerMessages) @if (this.provideCompilerMessages)
@@ -28,7 +28,22 @@ public partial class AssistantCoding : AssistantBaseCore
private bool provideCompilerMessages; private bool provideCompilerMessages;
private string compilerMessages = string.Empty; private string compilerMessages = string.Empty;
private string questions = string.Empty; private string questions = string.Empty;
#region Overrides of ComponentBase
protected override async Task OnInitializedAsync()
{
if (this.SettingsManager.ConfigurationData.PreselectCodingOptions)
{
this.provideCompilerMessages = this.SettingsManager.ConfigurationData.PreselectCodingCompilerMessages;
this.providerSettings = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.SettingsManager.ConfigurationData.PreselectedCodingProvider);
}
await base.OnInitializedAsync();
}
#endregion
private string? ValidatingCompilerMessages(string checkCompilerMessages) private string? ValidatingCompilerMessages(string checkCompilerMessages)
{ {
if(!this.provideCompilerMessages) if(!this.provideCompilerMessages)
@@ -53,6 +68,8 @@ public partial class AssistantCoding : AssistantBaseCore
this.codingContexts.Add(new() this.codingContexts.Add(new()
{ {
Id = $"Context {this.codingContexts.Count + 1}", Id = $"Context {this.codingContexts.Count + 1}",
Language = this.SettingsManager.ConfigurationData.PreselectCodingOptions ? this.SettingsManager.ConfigurationData.PreselectedCodingLanguage : default,
OtherLanguage = this.SettingsManager.ConfigurationData.PreselectCodingOptions ? this.SettingsManager.ConfigurationData.PreselectedCodingOtherLanguage : string.Empty,
}); });
} }
@@ -5,6 +5,21 @@ public partial class AssistantIconFinder : AssistantBaseCore
private string inputContext = string.Empty; private string inputContext = string.Empty;
private IconSources selectedIconSource; private IconSources selectedIconSource;
#region Overrides of ComponentBase
protected override async Task OnInitializedAsync()
{
if (this.SettingsManager.ConfigurationData.PreselectIconOptions)
{
this.selectedIconSource = this.SettingsManager.ConfigurationData.PreselectedIconSource;
this.providerSettings = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.SettingsManager.ConfigurationData.PreselectedIconProvider);
}
await base.OnInitializedAsync();
}
#endregion
protected override string Title => "Icon Finder"; protected override string Title => "Icon Finder";
protected override string Description => protected override string Description =>
@@ -1,5 +1,9 @@
@page "/settings" @page "/settings"
@using AIStudio.Components.Pages.Coding
@using AIStudio.Components.Pages.TextSummarizer
@using AIStudio.Provider @using AIStudio.Provider
@using AIStudio.Settings
@using AIStudio.Tools
@using Host = AIStudio.Provider.SelfHosted.Host @using Host = AIStudio.Provider.SelfHosted.Host
<MudText Typo="Typo.h3" Class="mb-12">Settings</MudText> <MudText Typo="Typo.h3" Class="mb-12">Settings</MudText>
@@ -59,20 +63,71 @@
<MudText Typo="Typo.h6" Class="mt-3">No providers configured yet.</MudText> <MudText Typo="Typo.h6" Class="mt-3">No providers configured yet.</MudText>
} }
<MudButton <MudButton Variant="Variant.Filled" Color="@Color.Primary" StartIcon="@Icons.Material.Filled.AddRoad" Class="mt-3 mb-6" OnClick="@this.AddProvider">
Variant="Variant.Filled" Color="@Color.Primary"
StartIcon="@Icons.Material.Filled.AddRoad"
Class="mt-3 mb-6" OnClick="@this.AddProvider">
Add Provider Add Provider
</MudButton> </MudButton>
<MudText Typo="Typo.h4" Class="mb-3">Options</MudText> <MudText Typo="Typo.h4" Class="mb-3">App Options</MudText>
<ConfigurationOption OptionDescription="Save energy?" LabelOn="Energy saving is enabled" LabelOff="Energy saving is disabled" State="@(() => this.SettingsManager.ConfigurationData.IsSavingEnergy)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.IsSavingEnergy = updatedState)" OptionHelp="When enabled, streamed content from the AI is updated once every third second. When disabled, streamed content will be updated as soon as it is available."/> <ConfigurationOption OptionDescription="Save energy?" LabelOn="Energy saving is enabled" LabelOff="Energy saving is disabled" State="@(() => this.SettingsManager.ConfigurationData.IsSavingEnergy)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.IsSavingEnergy = updatedState)" OptionHelp="When enabled, streamed content from the AI is updated once every third second. When disabled, streamed content will be updated as soon as it is available."/>
<ConfigurationOption OptionDescription="Enable spellchecking?" LabelOn="Spellchecking is enabled" LabelOff="Spellchecking is disabled" State="@(() => this.SettingsManager.ConfigurationData.EnableSpellchecking)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.EnableSpellchecking = updatedState)" OptionHelp="When enabled, spellchecking will be active in all input fields. Depending on your operating system, errors may not be visually highlighted, but right-clicking may still offer possible corrections." /> <ConfigurationOption OptionDescription="Enable spellchecking?" LabelOn="Spellchecking is enabled" LabelOff="Spellchecking is disabled" State="@(() => this.SettingsManager.ConfigurationData.EnableSpellchecking)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.EnableSpellchecking = updatedState)" OptionHelp="When enabled, spellchecking will be active in all input fields. Depending on your operating system, errors may not be visually highlighted, but right-clicking may still offer possible corrections." />
<ConfigurationSelect OptionDescription="Shortcut to send input" SelectedValue="@(() => this.SettingsManager.ConfigurationData.ShortcutSendBehavior)" Data="@ConfigurationSelectDataFactory.GetSendBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.ShortcutSendBehavior = selectedValue)" OptionHelp="Do you want to use any shortcut to send your input?"/>
<ConfigurationSelect OptionDescription="Check for updates" SelectedValue="@(() => this.SettingsManager.ConfigurationData.UpdateBehavior)" Data="@ConfigurationSelectDataFactory.GetUpdateBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.UpdateBehavior = selectedValue)" OptionHelp="How often should we check for app updates?"/> <ConfigurationSelect OptionDescription="Check for updates" SelectedValue="@(() => this.SettingsManager.ConfigurationData.UpdateBehavior)" Data="@ConfigurationSelectDataFactory.GetUpdateBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.UpdateBehavior = selectedValue)" OptionHelp="How often should we check for app updates?"/>
<ConfigurationSelect OptionDescription="Navigation bar behavior" SelectedValue="@(() => this.SettingsManager.ConfigurationData.NavigationBehavior)" Data="@ConfigurationSelectDataFactory.GetNavBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.NavigationBehavior = selectedValue)" OptionHelp="Select the desired behavior for the navigation bar."/>
<MudText Typo="Typo.h4" Class="mb-3">Chat Options</MudText>
<ConfigurationSelect OptionDescription="Shortcut to send input" SelectedValue="@(() => this.SettingsManager.ConfigurationData.ShortcutSendBehavior)" Data="@ConfigurationSelectDataFactory.GetSendBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.ShortcutSendBehavior = selectedValue)" OptionHelp="Do you want to use any shortcut to send your input?"/>
<MudText Typo="Typo.h4" Class="mb-3">Workspace Options</MudText>
<ConfigurationSelect OptionDescription="Workspace behavior" SelectedValue="@(() => this.SettingsManager.ConfigurationData.WorkspaceStorageBehavior)" Data="@ConfigurationSelectDataFactory.GetWorkspaceStorageBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.WorkspaceStorageBehavior = selectedValue)" OptionHelp="Should we store your chats?"/> <ConfigurationSelect OptionDescription="Workspace behavior" SelectedValue="@(() => this.SettingsManager.ConfigurationData.WorkspaceStorageBehavior)" Data="@ConfigurationSelectDataFactory.GetWorkspaceStorageBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.WorkspaceStorageBehavior = selectedValue)" OptionHelp="Should we store your chats?"/>
<ConfigurationSelect OptionDescription="Workspace maintenance" SelectedValue="@(() => this.SettingsManager.ConfigurationData.WorkspaceStorageTemporaryMaintenancePolicy)" Data="@ConfigurationSelectDataFactory.GetWorkspaceStorageTemporaryMaintenancePolicyData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.WorkspaceStorageTemporaryMaintenancePolicy = selectedValue)" OptionHelp="If and when should we delete your temporary chats?"/> <ConfigurationSelect OptionDescription="Workspace maintenance" SelectedValue="@(() => this.SettingsManager.ConfigurationData.WorkspaceStorageTemporaryMaintenancePolicy)" Data="@ConfigurationSelectDataFactory.GetWorkspaceStorageTemporaryMaintenancePolicyData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.WorkspaceStorageTemporaryMaintenancePolicy = selectedValue)" OptionHelp="If and when should we delete your temporary chats?"/>
<ConfigurationSelect OptionDescription="Navigation bar behavior" SelectedValue="@(() => this.SettingsManager.ConfigurationData.NavigationBehavior)" Data="@ConfigurationSelectDataFactory.GetNavBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.NavigationBehavior = selectedValue)" OptionHelp="Select the desired behavior for the navigation bar."/>
<MudText Typo="Typo.h4" Class="mb-3">Assistants Options</MudText>
<MudText Typo="Typo.h5" Class="mb-3">Icon Finder Options</MudText>
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
<ConfigurationOption OptionDescription="Preselect icon options?" LabelOn="Icon options are preselected" LabelOff="No icon options are preselected" State="@(() => this.SettingsManager.ConfigurationData.PreselectIconOptions)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.PreselectIconOptions = updatedState)" OptionHelp="When enabled, you can preselect the icon options. This is might be useful when you prefer a specific icon source or LLM model."/>
<ConfigurationSelect OptionDescription="Preselect the icon source" Disabled="@(() => !this.SettingsManager.ConfigurationData.PreselectIconOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.PreselectedIconSource)" Data="@ConfigurationSelectDataFactory.GetIconSourcesData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.PreselectedIconSource = selectedValue)" OptionHelp="Which icon source should be preselected?"/>
<ConfigurationProviderSelection Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.PreselectIconOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.PreselectedIconProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.PreselectedIconProvider = selectedValue)"/>
</MudPaper>
<MudText Typo="Typo.h5" Class="mb-3">Translator Options</MudText>
<ConfigurationSlider T="int" OptionDescription="How fast should the live translation react?" Min="500" Max="3_000" Step="100" Unit="milliseconds" Value="@(() => this.SettingsManager.ConfigurationData.LiveTranslationDebounceIntervalMilliseconds)" ValueUpdate="@(updatedValue => this.SettingsManager.ConfigurationData.LiveTranslationDebounceIntervalMilliseconds = updatedValue)"/>
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
<ConfigurationOption OptionDescription="Preselect translator options?" LabelOn="Translator options are preselected" LabelOff="No translator options are preselected" State="@(() => this.SettingsManager.ConfigurationData.PreselectTranslationOptions)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.PreselectTranslationOptions = updatedState)" OptionHelp="When enabled, you can preselect the translator options. This is might be useful when you prefer a specific target language or LLM model."/>
<ConfigurationOption OptionDescription="Preselect live translation?" Disabled="@(() => !this.SettingsManager.ConfigurationData.PreselectTranslationOptions)" LabelOn="Live translation is preselected" LabelOff="Live translation is not preselected" State="@(() => this.SettingsManager.ConfigurationData.PreselectLiveTranslation)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.PreselectLiveTranslation = updatedState)" />
<ConfigurationSelect OptionDescription="Preselect the target language" Disabled="@(() => !this.SettingsManager.ConfigurationData.PreselectTranslationOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.PreselectedTranslationTargetLanguage)" Data="@ConfigurationSelectDataFactory.GetCommonLanguagesData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.PreselectedTranslationTargetLanguage = selectedValue)" OptionHelp="Which target language should be preselected?"/>
@if (this.SettingsManager.ConfigurationData.PreselectedTranslationTargetLanguage is CommonLanguages.OTHER)
{
<ConfigurationText OptionDescription="Preselect another target language" Disabled="@(() => !this.SettingsManager.ConfigurationData.PreselectTranslationOptions)" Icon="@Icons.Material.Filled.Translate" Text="@(() => this.SettingsManager.ConfigurationData.PreselectTranslationOtherLanguage)" TextUpdate="@(updatedText => this.SettingsManager.ConfigurationData.PreselectTranslationOtherLanguage = updatedText)"/>
}
<ConfigurationProviderSelection Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.PreselectTranslationOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.PreselectedTranslationProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.PreselectedTranslationProvider = selectedValue)"/>
</MudPaper>
<MudText Typo="Typo.h5" Class="mb-3">Coding Options</MudText>
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
<ConfigurationOption OptionDescription="Preselect coding options?" LabelOn="Coding options are preselected" LabelOff="No coding options are preselected" State="@(() => this.SettingsManager.ConfigurationData.PreselectCodingOptions)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.PreselectCodingOptions = updatedState)" OptionHelp="When enabled, you can preselect the coding options. This is might be useful when you prefer a specific programming language or LLM model."/>
<ConfigurationOption OptionDescription="Preselect compiler messages?" Disabled="@(() => !this.SettingsManager.ConfigurationData.PreselectCodingOptions)" LabelOn="Compiler messages are preselected" LabelOff="Compiler messages are not preselected" State="@(() => this.SettingsManager.ConfigurationData.PreselectCodingCompilerMessages)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.PreselectCodingCompilerMessages = updatedState)" />
<ConfigurationSelect OptionDescription="Preselect a programming language" Disabled="@(() => !this.SettingsManager.ConfigurationData.PreselectCodingOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.PreselectedCodingLanguage)" Data="@ConfigurationSelectDataFactory.GetCommonCodingLanguagesData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.PreselectedCodingLanguage = selectedValue)" OptionHelp="Which programming language should be preselected for added contexts?"/>
@if (this.SettingsManager.ConfigurationData.PreselectedCodingLanguage is CommonCodingLanguages.OTHER)
{
<ConfigurationText OptionDescription="Preselect another programming language" Disabled="@(() => !this.SettingsManager.ConfigurationData.PreselectCodingOptions)" Icon="@Icons.Material.Filled.Code" Text="@(() => this.SettingsManager.ConfigurationData.PreselectedCodingOtherLanguage)" TextUpdate="@(updatedText => this.SettingsManager.ConfigurationData.PreselectedCodingOtherLanguage = updatedText)"/>
}
<ConfigurationProviderSelection Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.PreselectCodingOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.PreselectedCodingProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.PreselectedCodingProvider = selectedValue)"/>
</MudPaper>
<MudText Typo="Typo.h5" Class="mb-3">Text Summarizer Options</MudText>
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
<ConfigurationOption OptionDescription="Preselect summarizer options?" LabelOn="Summarizer options are preselected" LabelOff="No summarizer options are preselected" State="@(() => this.SettingsManager.ConfigurationData.PreselectTextSummarizerOptions)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.PreselectTextSummarizerOptions = updatedState)" OptionHelp="When enabled, you can preselect the text summarizer options. This is might be useful when you prefer a specific language, complexity, or LLM."/>
<ConfigurationSelect OptionDescription="Preselect the target language" Disabled="@(() => !this.SettingsManager.ConfigurationData.PreselectTextSummarizerOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.PreselectedTextSummarizerTargetLanguage)" Data="@ConfigurationSelectDataFactory.GetCommonLanguagesData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.PreselectedTextSummarizerTargetLanguage = selectedValue)" OptionHelp="Which target language should be preselected?"/>
@if (this.SettingsManager.ConfigurationData.PreselectedTextSummarizerTargetLanguage is CommonLanguages.OTHER)
{
<ConfigurationText OptionDescription="Preselect another target language" Disabled="@(() => !this.SettingsManager.ConfigurationData.PreselectTextSummarizerOptions)" Icon="@Icons.Material.Filled.Translate" Text="@(() => this.SettingsManager.ConfigurationData.PreselectedTextSummarizerOtherLanguage)" TextUpdate="@(updatedText => this.SettingsManager.ConfigurationData.PreselectedTextSummarizerOtherLanguage = updatedText)"/>
}
<ConfigurationSelect OptionDescription="Preselect the summarizer complexity" Disabled="@(() => !this.SettingsManager.ConfigurationData.PreselectTextSummarizerOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.PreselectedTextSummarizerComplexity)" Data="@ConfigurationSelectDataFactory.GetComplexityData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.PreselectedTextSummarizerComplexity = selectedValue)" OptionHelp="Which summarizer complexity should be preselected?"/>
@if(this.SettingsManager.ConfigurationData.PreselectedTextSummarizerComplexity is Complexity.SCIENTIFIC_LANGUAGE_OTHER_EXPERTS)
{
<ConfigurationText OptionDescription="Preselect your expertise" Disabled="@(() => !this.SettingsManager.ConfigurationData.PreselectTextSummarizerOptions)" Icon="@Icons.Material.Filled.Person" Text="@(() => this.SettingsManager.ConfigurationData.PreselectedTextSummarizerExpertInField)" TextUpdate="@(updatedText => this.SettingsManager.ConfigurationData.PreselectedTextSummarizerExpertInField = updatedText)"/>
}
<ConfigurationProviderSelection Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.PreselectTextSummarizerOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.PreselectedTextSummarizerProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.PreselectedTextSummarizerProvider = selectedValue)"/>
</MudPaper>
</MudPaper> </MudPaper>
</InnerScrolling> </InnerScrolling>
@@ -11,7 +11,7 @@ using DialogOptions = AIStudio.Components.CommonDialogs.DialogOptions;
namespace AIStudio.Components.Pages; namespace AIStudio.Components.Pages;
public partial class Settings : ComponentBase public partial class Settings : ComponentBase, IMessageBusReceiver, IDisposable
{ {
[Inject] [Inject]
public SettingsManager SettingsManager { get; init; } = null!; public SettingsManager SettingsManager { get; init; } = null!;
@@ -24,6 +24,22 @@ public partial class Settings : ComponentBase
[Inject] [Inject]
protected MessageBus MessageBus { get; init; } = null!; protected MessageBus MessageBus { get; init; } = null!;
private readonly List<ConfigurationSelectData<string>> availableProviders = new();
#region Overrides of ComponentBase
protected override async Task OnInitializedAsync()
{
// Register this component with the message bus:
this.MessageBus.RegisterComponent(this);
this.MessageBus.ApplyFilters(this, [], [ Event.CONFIGURATION_CHANGED ]);
this.UpdateProviders();
await base.OnInitializedAsync();
}
#endregion
#region Provider related #region Provider related
@@ -43,6 +59,8 @@ public partial class Settings : ComponentBase
addedProvider = addedProvider with { Num = this.SettingsManager.ConfigurationData.NextProviderNum++ }; addedProvider = addedProvider with { Num = this.SettingsManager.ConfigurationData.NextProviderNum++ };
this.SettingsManager.ConfigurationData.Providers.Add(addedProvider); this.SettingsManager.ConfigurationData.Providers.Add(addedProvider);
this.UpdateProviders();
await this.SettingsManager.StoreSettings(); await this.SettingsManager.StoreSettings();
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED); await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
} }
@@ -75,6 +93,8 @@ public partial class Settings : ComponentBase
editedProvider = editedProvider with { Num = this.SettingsManager.ConfigurationData.NextProviderNum++ }; editedProvider = editedProvider with { Num = this.SettingsManager.ConfigurationData.NextProviderNum++ };
this.SettingsManager.ConfigurationData.Providers[this.SettingsManager.ConfigurationData.Providers.IndexOf(provider)] = editedProvider; this.SettingsManager.ConfigurationData.Providers[this.SettingsManager.ConfigurationData.Providers.IndexOf(provider)] = editedProvider;
this.UpdateProviders();
await this.SettingsManager.StoreSettings(); await this.SettingsManager.StoreSettings();
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED); await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
} }
@@ -99,6 +119,7 @@ public partial class Settings : ComponentBase
await this.SettingsManager.StoreSettings(); await this.SettingsManager.StoreSettings();
} }
this.UpdateProviders();
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED); await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
} }
@@ -128,6 +149,43 @@ public partial class Settings : ComponentBase
var modelName = provider.Model.ToString(); var modelName = provider.Model.ToString();
return modelName.Length > MAX_LENGTH ? "[...] " + modelName[^Math.Min(MAX_LENGTH, modelName.Length)..] : modelName; return modelName.Length > MAX_LENGTH ? "[...] " + modelName[^Math.Min(MAX_LENGTH, modelName.Length)..] : modelName;
} }
private void UpdateProviders()
{
this.availableProviders.Clear();
foreach (var provider in this.SettingsManager.ConfigurationData.Providers)
this.availableProviders.Add(new (provider.InstanceName, provider.Id));
}
#endregion
#region Implementation of IMessageBusReceiver
public Task ProcessMessage<TMsg>(ComponentBase? sendingComponent, Event triggeredEvent, TMsg? data)
{
switch (triggeredEvent)
{
case Event.CONFIGURATION_CHANGED:
this.StateHasChanged();
break;
}
return Task.CompletedTask;
}
public Task<TResult?> ProcessMessageWithResult<TPayload, TResult>(ComponentBase? sendingComponent, Event triggeredEvent, TPayload? data)
{
return Task.FromResult<TResult?>(default);
}
#endregion
#region Implementation of IDisposable
public void Dispose()
{
this.MessageBus.Unregister(this);
}
#endregion #endregion
} }
@@ -29,6 +29,24 @@ public partial class AssistantTextSummarizer : AssistantBaseCore
private Complexity selectedComplexity; private Complexity selectedComplexity;
private string expertInField = string.Empty; private string expertInField = string.Empty;
#region Overrides of ComponentBase
protected override async Task OnInitializedAsync()
{
if(this.SettingsManager.ConfigurationData.PreselectTextSummarizerOptions)
{
this.selectedTargetLanguage = this.SettingsManager.ConfigurationData.PreselectedTextSummarizerTargetLanguage;
this.customTargetLanguage = this.SettingsManager.ConfigurationData.PreselectedTextSummarizerOtherLanguage;
this.selectedComplexity = this.SettingsManager.ConfigurationData.PreselectedTextSummarizerComplexity;
this.expertInField = this.SettingsManager.ConfigurationData.PreselectedTextSummarizerExpertInField;
this.providerSettings = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.SettingsManager.ConfigurationData.PreselectedTextSummarizerProvider);
}
await base.OnInitializedAsync();
}
#endregion
private string? ValidatingText(string text) private string? ValidatingText(string text)
{ {
if(string.IsNullOrWhiteSpace(text)) if(string.IsNullOrWhiteSpace(text))
@@ -1,10 +1,10 @@
@page "/assistant/translator" @page "/assistant/translation"
@using AIStudio.Settings @using AIStudio.Settings
@using AIStudio.Tools @using AIStudio.Tools
@inherits AssistantBaseCore @inherits AssistantBaseCore
<MudField Label="Live translation" Variant="Variant.Outlined" Class="mb-3"> <MudField Label="Live translation" Variant="Variant.Outlined" Class="mb-3">
<MudSwitch T="bool" @bind-Value="@this.liveTranslation"> <MudSwitch T="bool" @bind-Value="@this.liveTranslation" Color="Color.Primary">
@(this.liveTranslation ? "Live translation" : "No live translation") @(this.liveTranslation ? "Live translation" : "No live translation")
</MudSwitch> </MudSwitch>
</MudField> </MudField>
@@ -1,10 +1,10 @@
using AIStudio.Tools; using AIStudio.Tools;
namespace AIStudio.Components.Pages.Translator; namespace AIStudio.Components.Pages.Translation;
public partial class AssistantTranslator : AssistantBaseCore public partial class AssistantTranslation : AssistantBaseCore
{ {
protected override string Title => "Translator"; protected override string Title => "Translation";
protected override string Description => protected override string Description =>
""" """
@@ -24,7 +24,24 @@ public partial class AssistantTranslator : AssistantBaseCore
private string inputTextLastTranslation = string.Empty; private string inputTextLastTranslation = string.Empty;
private CommonLanguages selectedTargetLanguage; private CommonLanguages selectedTargetLanguage;
private string customTargetLanguage = string.Empty; private string customTargetLanguage = string.Empty;
#region Overrides of ComponentBase
protected override async Task OnInitializedAsync()
{
if (this.SettingsManager.ConfigurationData.PreselectTranslationOptions)
{
this.liveTranslation = this.SettingsManager.ConfigurationData.PreselectLiveTranslation;
this.selectedTargetLanguage = this.SettingsManager.ConfigurationData.PreselectedTranslationTargetLanguage;
this.customTargetLanguage = this.SettingsManager.ConfigurationData.PreselectTranslationOtherLanguage;
this.providerSettings = this.SettingsManager.ConfigurationData.Providers.FirstOrDefault(x => x.Id == this.SettingsManager.ConfigurationData.PreselectedTranslationProvider);
}
await base.OnInitializedAsync();
}
#endregion
private string? ValidatingText(string text) private string? ValidatingText(string text)
{ {
if(string.IsNullOrWhiteSpace(text)) if(string.IsNullOrWhiteSpace(text))
@@ -1,6 +1,6 @@
using AIStudio.Tools; using AIStudio.Tools;
namespace AIStudio.Components.Pages.Translator; namespace AIStudio.Components.Pages.Translation;
public static class CommonLanguageExtension public static class CommonLanguageExtension
{ {
@@ -1,6 +1,10 @@
using AIStudio.Settings; using AIStudio.Components.Pages.Coding;
using AIStudio.Components.Pages.IconFinder;
using AIStudio.Components.Pages.TextSummarizer;
using AIStudio.Settings.DataModel;
using AIStudio.Tools;
namespace AIStudio.Components; namespace AIStudio.Settings;
/// <summary> /// <summary>
/// A data structure to map a name to a value. /// A data structure to map a name to a value.
@@ -55,4 +59,28 @@ public static class ConfigurationSelectDataFactory
yield return new("Navigation never expands, no tooltips", NavBehavior.NEVER_EXPAND_NO_TOOLTIPS); yield return new("Navigation never expands, no tooltips", NavBehavior.NEVER_EXPAND_NO_TOOLTIPS);
yield return new("Always expand navigation", NavBehavior.ALWAYS_EXPAND); yield return new("Always expand navigation", NavBehavior.ALWAYS_EXPAND);
} }
public static IEnumerable<ConfigurationSelectData<IconSources>> GetIconSourcesData()
{
foreach (var source in Enum.GetValues<IconSources>())
yield return new(source.Name(), source);
}
public static IEnumerable<ConfigurationSelectData<CommonLanguages>> GetCommonLanguagesData()
{
foreach (var language in Enum.GetValues<CommonLanguages>())
yield return new(language.Name(), language);
}
public static IEnumerable<ConfigurationSelectData<CommonCodingLanguages>> GetCommonCodingLanguagesData()
{
foreach (var language in Enum.GetValues<CommonCodingLanguages>())
yield return new(language.Name(), language);
}
public static IEnumerable<ConfigurationSelectData<Complexity>> GetComplexityData()
{
foreach (var complexity in Enum.GetValues<Complexity>())
yield return new(complexity.Name(), complexity);
}
} }
-59
View File
@@ -1,59 +0,0 @@
namespace AIStudio.Settings;
/// <summary>
/// The data model for the settings file.
/// </summary>
public sealed class Data
{
/// <summary>
/// The version of the settings file. Allows us to upgrade the settings
/// when a new version is available.
/// </summary>
public Version Version { get; init; } = Version.V3;
/// <summary>
/// List of configured providers.
/// </summary>
public List<Provider> Providers { get; init; } = [];
/// <summary>
/// The next provider number to use.
/// </summary>
public uint NextProviderNum { get; set; } = 1;
/// <summary>
/// Should we save energy? When true, we will update content streamed
/// from the server, i.e., AI, less frequently.
/// </summary>
public bool IsSavingEnergy { get; set; }
/// <summary>
/// Shortcuts to send the input to the AI.
/// </summary>
public SendBehavior ShortcutSendBehavior { get; set; } = SendBehavior.MODIFER_ENTER_IS_SENDING;
/// <summary>
/// Should we enable spellchecking for all input fields?
/// </summary>
public bool EnableSpellchecking { get; set; }
/// <summary>
/// If and when we should look for updates.
/// </summary>
public UpdateBehavior UpdateBehavior { get; set; } = UpdateBehavior.ONCE_STARTUP;
/// <summary>
/// The chat storage behavior.
/// </summary>
public WorkspaceStorageBehavior WorkspaceStorageBehavior { get; set; } = WorkspaceStorageBehavior.STORE_CHATS_AUTOMATICALLY;
/// <summary>
/// The chat storage maintenance behavior.
/// </summary>
public WorkspaceStorageTemporaryMaintenancePolicy WorkspaceStorageTemporaryMaintenancePolicy { get; set; } = WorkspaceStorageTemporaryMaintenancePolicy.DELETE_OLDER_THAN_90_DAYS;
/// <summary>
/// The navigation behavior.
/// </summary>
public NavBehavior NavigationBehavior { get; set; } = NavBehavior.EXPAND_ON_HOVER;
}
@@ -0,0 +1,192 @@
using AIStudio.Components.Pages.Coding;
using AIStudio.Components.Pages.IconFinder;
using AIStudio.Components.Pages.TextSummarizer;
using AIStudio.Tools;
namespace AIStudio.Settings.DataModel;
/// <summary>
/// The data model for the settings file.
/// </summary>
public sealed class Data
{
/// <summary>
/// The version of the settings file. Allows us to upgrade the settings
/// when a new version is available.
/// </summary>
public Version Version { get; init; } = Version.V3;
/// <summary>
/// List of configured providers.
/// </summary>
public List<Provider> Providers { get; init; } = [];
/// <summary>
/// The next provider number to use.
/// </summary>
public uint NextProviderNum { get; set; } = 1;
#region App Settings
/// <summary>
/// Should we save energy? When true, we will update content streamed
/// from the server, i.e., AI, less frequently.
/// </summary>
public bool IsSavingEnergy { get; set; }
/// <summary>
/// Should we enable spellchecking for all input fields?
/// </summary>
public bool EnableSpellchecking { get; set; }
/// <summary>
/// If and when we should look for updates.
/// </summary>
public UpdateBehavior UpdateBehavior { get; set; } = UpdateBehavior.ONCE_STARTUP;
/// <summary>
/// The navigation behavior.
/// </summary>
public NavBehavior NavigationBehavior { get; set; } = NavBehavior.EXPAND_ON_HOVER;
#endregion
#region Chat Settings
/// <summary>
/// Shortcuts to send the input to the AI.
/// </summary>
public SendBehavior ShortcutSendBehavior { get; set; } = SendBehavior.MODIFER_ENTER_IS_SENDING;
#endregion
#region Workspace Settings
/// <summary>
/// The chat storage behavior.
/// </summary>
public WorkspaceStorageBehavior WorkspaceStorageBehavior { get; set; } = WorkspaceStorageBehavior.STORE_CHATS_AUTOMATICALLY;
/// <summary>
/// The chat storage maintenance behavior.
/// </summary>
public WorkspaceStorageTemporaryMaintenancePolicy WorkspaceStorageTemporaryMaintenancePolicy { get; set; } = WorkspaceStorageTemporaryMaintenancePolicy.DELETE_OLDER_THAN_90_DAYS;
#endregion
#region Assiatant: Icon Finder Settings
/// <summary>
/// Do we want to preselect any icon options?
/// </summary>
public bool PreselectIconOptions { get; set; }
/// <summary>
/// The preselected icon source.
/// </summary>
public IconSources PreselectedIconSource { get; set; }
/// <summary>
/// The preselected icon provider.
/// </summary>
public string PreselectedIconProvider { get; set; } = string.Empty;
#endregion
#region Assistant: Translation Settings
/// <summary>
/// The live translation interval for debouncing in milliseconds.
/// </summary>
public int LiveTranslationDebounceIntervalMilliseconds { get; set; } = 1_000;
/// <summary>
/// Do we want to preselect any translator options?
/// </summary>
public bool PreselectTranslationOptions { get; set; }
/// <summary>
/// Preselect the live translation?
/// </summary>
public bool PreselectLiveTranslation { get; set; }
/// <summary>
/// Preselect the target language?
/// </summary>
public CommonLanguages PreselectedTranslationTargetLanguage { get; set; } = CommonLanguages.EN_US;
/// <summary>
/// Preselect any other language?
/// </summary>
public string PreselectTranslationOtherLanguage { get; set; } = string.Empty;
/// <summary>
/// The preselected translator provider.
/// </summary>
public string PreselectedTranslationProvider { get; set; } = string.Empty;
#endregion
#region Assistant: Coding Settings
/// <summary>
/// Preselect any coding options?
/// </summary>
public bool PreselectCodingOptions { get; set; }
/// <summary>
/// Preselect the compiler messages?
/// </summary>
public bool PreselectCodingCompilerMessages { get; set; }
/// <summary>
/// Preselect the coding language for new contexts?
/// </summary>
public CommonCodingLanguages PreselectedCodingLanguage { get; set; }
/// <summary>
/// Do you want to preselect any other language?
/// </summary>
public string PreselectedCodingOtherLanguage { get; set; } = string.Empty;
/// <summary>
/// Which coding provider should be preselected?
/// </summary>
public string PreselectedCodingProvider { get; set; } = string.Empty;
#endregion
#region Assistant: Text Summarizer Settings
/// <summary>
/// Preselect any text summarizer options?
/// </summary>
public bool PreselectTextSummarizerOptions { get; set; }
/// <summary>
/// Preselect the target language?
/// </summary>
public CommonLanguages PreselectedTextSummarizerTargetLanguage { get; set; }
/// <summary>
/// Preselect any other language?
/// </summary>
public string PreselectedTextSummarizerOtherLanguage { get; set; } = string.Empty;
/// <summary>
/// Preselect the complexity?
/// </summary>
public Complexity PreselectedTextSummarizerComplexity { get; set; }
/// <summary>
/// Preselect any expertise in a field?
/// </summary>
public string PreselectedTextSummarizerExpertInField { get; set; } = string.Empty;
/// <summary>
/// Preselect a text summarizer provider?
/// </summary>
public string PreselectedTextSummarizerProvider { get; set; } = string.Empty;
#endregion
}
@@ -1,4 +1,4 @@
namespace AIStudio.Settings; namespace AIStudio.Settings.DataModel;
public enum NavBehavior public enum NavBehavior
{ {
@@ -1,4 +1,4 @@
namespace AIStudio.Settings; namespace AIStudio.Settings.DataModel;
/// <summary> /// <summary>
/// Possible behaviors for sending the input to the AI. /// Possible behaviors for sending the input to the AI.
@@ -1,4 +1,4 @@
namespace AIStudio.Settings; namespace AIStudio.Settings.DataModel;
public enum UpdateBehavior public enum UpdateBehavior
{ {
@@ -1,4 +1,4 @@
namespace AIStudio.Settings; namespace AIStudio.Settings.DataModel;
public enum WorkspaceStorageBehavior public enum WorkspaceStorageBehavior
{ {
@@ -1,4 +1,4 @@
namespace AIStudio.Settings; namespace AIStudio.Settings.DataModel;
public enum WorkspaceStorageTemporaryMaintenancePolicy public enum WorkspaceStorageTemporaryMaintenancePolicy
{ {
@@ -1,6 +1,7 @@
@using AIStudio.Provider @using AIStudio.Provider
@using AIStudio.Provider.SelfHosted @using AIStudio.Provider.SelfHosted
@using MudBlazor @using MudBlazor
@using AIStudio.Components.Blocks
<MudDialog> <MudDialog>
<DialogContent> <DialogContent>
@@ -92,21 +93,7 @@
/> />
</MudForm> </MudForm>
<Issues IssuesData="@this.dataIssues"/>
@if (this.dataIssues.Any())
{
<MudPaper Class="pa-2 mt-3">
<MudText Typo="Typo.h6">Issues</MudText>
<MudList T="string">
@foreach (var issue in this.dataIssues)
{
<MudListItem T="string" Icon="@Icons.Material.Filled.Error" IconColor="Color.Error">
@issue
</MudListItem>
}
</MudList>
</MudPaper>
}
</DialogContent> </DialogContent>
<DialogActions> <DialogActions>
<MudButton OnClick="@this.Cancel" Variant="Variant.Filled">Cancel</MudButton> <MudButton OnClick="@this.Cancel" Variant="Variant.Filled">Cancel</MudButton>
@@ -1,5 +1,6 @@
using System.Text.Json; using System.Text.Json;
using AIStudio.Provider; using AIStudio.Provider;
using AIStudio.Settings.DataModel;
// ReSharper disable NotAccessedPositionalProperty.Local // ReSharper disable NotAccessedPositionalProperty.Local
@@ -72,9 +73,10 @@ public sealed class SettingsManager
/// <summary> /// <summary>
/// Data structure for deleting a secret response. /// Data structure for deleting a secret response.
/// </summary> /// </summary>
/// <param name="Success">True, when the secret was successfully deleted.</param> /// <param name="Success">True, when the secret was successfully deleted or not found.</param>
/// <param name="Issue">The issue, when the secret could not be deleted.</param> /// <param name="Issue">The issue, when the secret could not be deleted.</param>
public readonly record struct DeleteSecretResponse(bool Success, string Issue); /// <param name="WasEntryFound">True, when the entry was found and deleted.</param>
public readonly record struct DeleteSecretResponse(bool Success, string Issue, bool WasEntryFound);
/// <summary> /// <summary>
/// Tries to delete the API key for the given provider. /// Tries to delete the API key for the given provider.
@@ -1,3 +1,5 @@
using AIStudio.Settings.DataModel;
using Host = AIStudio.Provider.SelfHosted.Host; using Host = AIStudio.Provider.SelfHosted.Host;
namespace AIStudio.Settings; namespace AIStudio.Settings;
@@ -1,4 +1,5 @@
using AIStudio.Settings; using AIStudio.Settings;
using AIStudio.Settings.DataModel;
namespace AIStudio.Tools; namespace AIStudio.Tools;
@@ -1,4 +1,5 @@
using AIStudio.Settings; using AIStudio.Settings;
using AIStudio.Settings.DataModel;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
@@ -0,0 +1,2 @@
# v0.8.4, build 166 (2024-07-26 06:53 UTC)
- Fixed issue #44: After upgrading to MudBlazor 7.x.x, text padding was off, and tooltips were not displayed correctly. This issue was shown only on releases, not on the development builds.
@@ -0,0 +1,14 @@
# v0.8.5, build 167 (2024-07-28 16:44 UTC)
- Added the possibility to provide default options for the icon finder assistant
- Added the possibility to provide default options for the translation assistant
- Added the possibility to provide default options for the coding assistant
- Added the possibility to provide default options for the text summarizer assistant
- Improved readability of the issue component
- Improved switches: when an option is enabled, the switch is using a different color
- Fixed the applying of spellchecking settings to the single-line dialog
- Fixed the bug where users cannot delete a self-hosted provider when an API token was never entered
- Fixed the bug where users were no longer able to move chats to workspaces, caused by the migration to MudBlazor 7.x.x
- Restructured the layout of the settings page
- Refactored the settings data model
- Upgraded to Rust 1.80.0
- Upgraded all Rust dependencies
@@ -2,4 +2,4 @@
* MudBlazor (https://mudblazor.com/) * MudBlazor (https://mudblazor.com/)
* Copyright (c) 2021 MudBlazor * Copyright (c) 2021 MudBlazor
* Licensed under MIT (https://github.com/MudBlazor/MudBlazor/blob/master/LICENSE) * Licensed under MIT (https://github.com/MudBlazor/MudBlazor/blob/master/LICENSE)
*/.mud-primary{background-color:var(--mud-palette-primary) !important}.mud-primary-text{color:var(--mud-palette-primary) !important}.mud-primary-hover{background-color:var(--mud-palette-primary-hover) !important}@media(hover: hover)and (pointer: fine){.hover\:mud-primary-hover:hover{background-color:var(--mud-palette-primary-hover) !important}}.hover\:mud-primary-hover:focus-visible,.hover\:mud-primary-hover:active{background-color:var(--mud-palette-primary-hover) !important}.mud-border-primary{border-color:var(--mud-palette-primary) !important}.mud-theme-primary{color:var(--mud-palette-primary-text) !important;background-color:var(--mud-palette-primary) !important}.mud-secondary{background-color:var(--mud-palette-secondary) !important}.mud-secondary-text{color:var(--mud-palette-secondary) !important}.mud-secondary-hover{background-color:var(--mud-palette-secondary-hover) !important}@media(hover: hover)and (pointer: fine){.hover\:mud-secondary-hover:hover{background-color:var(--mud-palette-secondary-hover) !important}}.hover\:mud-secondary-hover:focus-visible,.hover\:mud-secondary-hover:active{background-color:var(--mud-palette-secondary-hover) !important}.mud-border-secondary{border-color:var(--mud-palette-secondary) !important}.mud-theme-secondary{color:var(--mud-palette-secondary-text) !important;background-color:var(--mud-palette-secondary) !important}.mud-tertiary{background-color:var(--mud-palette-tertiary) !important}.mud-tertiary-text{color:var(--mud-palette-tertiary) !important}.mud-tertiary-hover{background-color:var(--mud-palette-tertiary-hover) !important}@media(hover: hover)and (pointer: fine){.hover\:mud-tertiary-hover:hover{background-color:var(--mud-palette-tertiary-hover) !important}}.hover\:mud-tertiary-hover:focus-visible,.hover\:mud-tertiary-hover:active{background-color:var(--mud-palette-tertiary-hover) !important}.mud-border-tertiary{border-color:var(--mud-palette-tertiary) !important}.mud-theme-tertiary{color:var(--mud-palette-tertiary-text) !important;background-color:var(--mud-palette-tertiary) !important}.mud-info{background-color:var(--mud-palette-info) !important}.mud-info-text{color:var(--mud-palette-info) !important}.mud-info-hover{background-color:var(--mud-palette-info-hover) !important}@media(hover: hover)and (pointer: fine){.hover\:mud-info-hover:hover{background-color:var(--mud-palette-info-hover) !important}}.hover\:mud-info-hover:focus-visible,.hover\:mud-info-hover:active{background-color:var(--mud-palette-info-hover) !important}.mud-border-info{border-color:var(--mud-palette-info) !important}.mud-theme-info{color:var(--mud-palette-info-text) !important;background-color:var(--mud-palette-info) !important}.mud-success{background-color:var(--mud-palette-success) !important}.mud-success-text{color:var(--mud-palette-success) !important}.mud-success-hover{background-color:var(--mud-palette-success-hover) !important}@media(hover: hover)and (pointer: fine){.hover\:mud-success-hover:hover{background-color:var(--mud-palette-success-hover) !important}}.hover\:mud-success-hover:focus-visible,.hover\:mud-success-hover:active{background-color:var(--mud-palette-success-hover) !important}.mud-border-success{border-color:var(--mud-palette-success) !important}.mud-theme-success{color:var(--mud-palette-success-text) !important;background-color:var(--mud-palette-success) !important}.mud-warning{background-color:var(--mud-palette-warning) !important}.mud-warning-text{color:var(--mud-palette-warning) !important}.mud-warning-hover{background-color:var(--mud-palette-warning-hover) !important}@media(hover: hover)and (pointer: fine){.hover\:mud-warning-hover:hover{background-color:var(--mud-palette-warning-hover) !important}}.hover\:mud-warning-hover:focus-visible,.hover\:mud-warning-hover:active{background-color:var(--mud-palette-warning-hover) !important}.mud-border-warning{border-color:var(--mud-palette-warning) !important}.mud-theme-warning{color:var(--mud-palette-warning-text) !important;background-color:var(--mud-palette-warning) !important}.mud-error{background-color:var(--mud-palette-error) !important}.mud-error-text{color:var(--mud-palette-error) !important}.mud-error-hover{background-color:var(--mud-palette-error-hover) !important}@media(hover: hover)and (pointer: fine){.hover\:mud-error-hover:hover{background-color:var(--mud-palette-error-hover) !important}}.hover\:mud-error-hover:focus-visible,.hover\:mud-error-hover:active{background-color:var(--mud-palette-error-hover) !important}.mud-border-error{border-color:var(--mud-palette-error) !important}.mud-theme-error{color:var(--mud-palette-error-text) !important;background-color:var(--mud-palette-error) !important}.mud-dark{background-color:var(--mud-palette-dark) !important}.mud-dark-text{color:var(--mud-palette-dark) !important}.mud-dark-hover{background-color:var(--mud-palette-dark-hover) !important}@media(hover: hover)and (pointer: fine){.hover\:mud-dark-hover:hover{background-color:var(--mud-palette-dark-hover) !important}}.hovLine truncated */.mud-primary{background-color:var(--mud-palette-primary) !important}.mud-primary-text{color:var(--mud-palette-primary) !important;--mud-ripple-color: var(--mud-palette-primary) !important}.mud-primary-hover{background-color:var(--mud-palette-primary-hover) !important}@media(hover: hover)and (pointer: fine){.hover\:mud-primary-hover:hover{background-color:var(--mud-palette-primary-hover) !important}}.hover\:mud-primary-hover:focus-visible,.hover\:mud-primary-hover:active{background-color:var(--mud-palette-primary-hover) !important}.mud-border-primary{border-color:var(--mud-palette-primary) !important}.mud-theme-primary{color:var(--mud-palette-primary-text) !important;background-color:var(--mud-palette-primary) !important}.mud-secondary{background-color:var(--mud-palette-secondary) !important}.mud-secondary-text{color:var(--mud-palette-secondary) !important;--mud-ripple-color: var(--mud-palette-secondary) !important}.mud-secondary-hover{background-color:var(--mud-palette-secondary-hover) !important}@media(hover: hover)and (pointer: fine){.hover\:mud-secondary-hover:hover{background-color:var(--mud-palette-secondary-hover) !important}}.hover\:mud-secondary-hover:focus-visible,.hover\:mud-secondary-hover:active{background-color:var(--mud-palette-secondary-hover) !important}.mud-border-secondary{border-color:var(--mud-palette-secondary) !important}.mud-theme-secondary{color:var(--mud-palette-secondary-text) !important;background-color:var(--mud-palette-secondary) !important}.mud-tertiary{background-color:var(--mud-palette-tertiary) !important}.mud-tertiary-text{color:var(--mud-palette-tertiary) !important;--mud-ripple-color: var(--mud-palette-tertiary) !important}.mud-tertiary-hover{background-color:var(--mud-palette-tertiary-hover) !important}@media(hover: hover)and (pointer: fine){.hover\:mud-tertiary-hover:hover{background-color:var(--mud-palette-tertiary-hover) !important}}.hover\:mud-tertiary-hover:focus-visible,.hover\:mud-tertiary-hover:active{background-color:var(--mud-palette-tertiary-hover) !important}.mud-border-tertiary{border-color:var(--mud-palette-tertiary) !important}.mud-theme-tertiary{color:var(--mud-palette-tertiary-text) !important;background-color:var(--mud-palette-tertiary) !important}.mud-info{background-color:var(--mud-palette-info) !important}.mud-info-text{color:var(--mud-palette-info) !important;--mud-ripple-color: var(--mud-palette-info) !important}.mud-info-hover{background-color:var(--mud-palette-info-hover) !important}@media(hover: hover)and (pointer: fine){.hover\:mud-info-hover:hover{background-color:var(--mud-palette-info-hover) !important}}.hover\:mud-info-hover:focus-visible,.hover\:mud-info-hover:active{background-color:var(--mud-palette-info-hover) !important}.mud-border-info{border-color:var(--mud-palette-info) !important}.mud-theme-info{color:var(--mud-palette-info-text) !important;background-color:var(--mud-palette-info) !important}.mud-success{background-color:var(--mud-palette-success) !important}.mud-success-text{color:var(--mud-palette-success) !important;--mud-ripple-color: var(--mud-palette-success) !important}.mud-success-hover{background-color:var(--mud-palette-success-hover) !important}@media(hover: hover)and (pointer: fine){.hover\:mud-success-hover:hover{background-color:var(--mud-palette-success-hover) !important}}.hover\:mud-success-hover:focus-visible,.hover\:mud-success-hover:active{background-color:var(--mud-palette-success-hover) !important}.mud-border-success{border-color:var(--mud-palette-success) !important}.mud-theme-success{color:var(--mud-palette-success-text) !important;background-color:var(--mud-palette-success) !important}.mud-warning{background-color:var(--mud-palette-warning) !important}.mud-warning-text{color:var(--mud-palette-warning) !important;--mud-ripple-color: var(--mud-palette-warning) !important}.mud-warning-hover{background-color:var(--mud-palette-warning-hover) !important}@media(hover: hover)and (pointer: fine){.hover\:mud-warning-hover:hover{background-color:var(--mud-palette-warning-hover) !important}}.hover\:mud-warning-hover:focus-visible,.hover\:mud-warning-hover:active{background-color:var(--mud-palette-warning-hover) !important}.mud-border-warning{border-color:var(--mud-palette-warning) !important}.mud-theme-warning{color:var(--mud-palette-warning-text) !important;background-color:var(--mud-palette-warning) !important}.mud-error{background-color:var(--mud-palette-error) !important}.mud-error-text{color:var(--mud-palette-error) !important;--mud-ripple-color: var(--mud-palette-error) !important}.mud-error-hover{background-color:var(--mud-palette-error-hover) !important}@media(hover: hover)and (pointer: fine){.hover\:mud-error-hover:hover{background-color:var(--mud-palette-error-hover) !important}}.hover\:mud-error-hover:focus-visible,.hover\:mud-error-hover:active{background-color:var(--mud-palette-error-hover) !important}.mud-border-error{border-color:var(--mud-palette-error) !important}.mud-theme-error{color:var(--mud-paleLine truncated
+172 -163
View File
@@ -1,11 +1,28 @@
window.mudDragAndDrop={initDropZone:(id)=>{const elem=document.getElementById('mud-drop-zone-'+id);elem.addEventListener('dragover',()=>event.preventDefault());elem.addEventListener('dragstart',()=>event.dataTransfer.setData('',event.target.id));},makeDropZonesNotRelative:()=>{var firstDropItems=Array.from(document.getElementsByClassName('mud-drop-item')).filter(x=>x.getAttribute('index')=="-1");for(let dropItem of firstDropItems){dropItem.style.position='static';} window.getTabbableElements=(element)=>{return element.querySelectorAll("a[href]:not([tabindex='-1']),"+"area[href]:not([tabindex='-1']),"+"button:not([disabled]):not([tabindex='-1']),"+"input:not([disabled]):not([tabindex='-1']):not([type='hidden']),"+"select:not([disabled]):not([tabindex='-1']),"+"textarea:not([disabled]):not([tabindex='-1']),"+"iframe:not([tabindex='-1']),"+"details:not([tabindex='-1']),"+"[tabindex]:not([tabindex='-1']),"+"[contentEditable=true]:not([tabindex='-1'])");};window.serializeParameter=(data,spec)=>{if(typeof data=="undefined"||data===null){return null;}
const dropZones=document.getElementsByClassName('mud-drop-zone');for(let dropZone of dropZones){dropZone.style.position='unset';}},getDropZoneIdentifierOnPosition:(x,y)=>{const elems=document.elementsFromPoint(x,y);const dropZones=elems.filter(e=>e.classList.contains('mud-drop-zone')) if(typeof data==="number"||typeof data==="string"||typeof data=="boolean"){return data;}
const dropZone=dropZones[0];if(dropZone){return dropZone.getAttribute('identifier')||"";} let res=(Array.isArray(data))?[]:{};if(!spec){spec="*";}
return"";},getDropIndexOnPosition:(x,y,id)=>{const elems=document.elementsFromPoint(x,y);const dropItems=elems.filter(e=>e.classList.contains('mud-drop-item')&&e.id!=('mud-drop-item-'+id)) for(let i in data){let currentMember=data[i];if(typeof currentMember==='function'||currentMember===null){continue;}
const dropItem=dropItems[0];if(dropItem){return dropItem.getAttribute('index')||"";} let currentMemberSpec;if(spec!="*"){currentMemberSpec=Array.isArray(data)?spec:spec[i];if(!currentMemberSpec){continue;}}else{currentMemberSpec="*"}
return"";},makeDropZonesRelative:()=>{const dropZones=document.getElementsByClassName('mud-drop-zone');for(let dropZone of dropZones){dropZone.style.position='relative';} if(typeof currentMember==='object'){if(Array.isArray(currentMember)||currentMember.length){res[i]=[];for(let j=0;j<currentMember.length;j++){const arrayItem=currentMember[j];if(typeof arrayItem==='object'){res[i].push(this.serializeParameter(arrayItem,currentMemberSpec));}else{res[i].push(arrayItem);}}}else{if(currentMember.length===0){res[i]=[];}else{res[i]=this.serializeParameter(currentMember,currentMemberSpec);}}}else{if(currentMember===Infinity){currentMember="Infinity";}
var firstDropItems=Array.from(document.getElementsByClassName('mud-drop-item')).filter(x=>x.getAttribute('index')=="-1");for(let dropItem of firstDropItems){dropItem.style.position='relative';}},moveItemByDifference:(id,dx,dy)=>{const elem=document.getElementById('mud-drop-item-'+id);var tx=(parseFloat(elem.getAttribute('data-x'))||0)+dx;var ty=(parseFloat(elem.getAttribute('data-y'))||0)+dy;elem.style.webkitTransform=elem.style.transform='translate3d('+tx+'px, '+ty+'px, 10px)';elem.setAttribute('data-x',tx);elem.setAttribute('data-y',ty);},resetItem:(id)=>{const elem=document.getElementById('mud-drop-item-'+id);if(elem){elem.style.webkitTransform=elem.style.transform='';elem.setAttribute('data-x',0);elem.setAttribute('data-y',0);}}};class MudKeyInterceptorFactory{connect(dotNetRef,elementId,options){if(!elementId) if(currentMember!==null){res[i]=currentMember;}}}
return res;};class MudResizeObserverFactory{constructor(){this._maps={};}
connect(id,dotNetRef,elements,elementIds,options){var existingEntry=this._maps[id];if(!existingEntry){var observer=new MudResizeObserver(dotNetRef,options);this._maps[id]=observer;}
var result=this._maps[id].connect(elements,elementIds);return result;}
disconnect(id,element){var existingEntry=this._maps[id];if(existingEntry){existingEntry.disconnect(element);}}
cancelListener(id){var existingEntry=this._maps[id];if(existingEntry){existingEntry.cancelListener();delete this._maps[id];}}}
class MudResizeObserver{constructor(dotNetRef,options){this.logger=options.enableLogging?console.log:(message)=>{};this.options=options;this._dotNetRef=dotNetRef
var delay=(this.options||{}).reportRate||200;this.throttleResizeHandlerId=-1;var observervedElements=[];this._observervedElements=observervedElements;this.logger('[MudBlazor | ResizeObserver] Observer initialized');this._resizeObserver=new ResizeObserver(entries=>{var changes=[];this.logger('[MudBlazor | ResizeObserver] changes detected');for(let entry of entries){var target=entry.target;var affectedObservedElement=observervedElements.find((x)=>x.element==target);if(affectedObservedElement){var size=entry.target.getBoundingClientRect();if(affectedObservedElement.isInitialized==true){changes.push({id:affectedObservedElement.id,size:size});}
else{affectedObservedElement.isInitialized=true;}}}
if(changes.length>0){if(this.throttleResizeHandlerId>=0){clearTimeout(this.throttleResizeHandlerId);}
this.throttleResizeHandlerId=window.setTimeout(this.resizeHandler.bind(this,changes),delay);}});}
resizeHandler(changes){try{this.logger("[MudBlazor | ResizeObserver] OnSizeChanged handler invoked");this._dotNetRef.invokeMethodAsync("OnSizeChanged",changes);}catch(error){this.logger("[MudBlazor | ResizeObserver] Error in OnSizeChanged handler:",{error});}}
connect(elements,ids){var result=[];this.logger('[MudBlazor | ResizeObserver] Start observing elements...');for(var i=0;i<elements.length;i++){var newEntry={element:elements[i],id:ids[i],isInitialized:false,};this.logger("[MudBlazor | ResizeObserver] Start observing element:",{newEntry});result.push(elements[i].getBoundingClientRect());this._observervedElements.push(newEntry);this._resizeObserver.observe(elements[i]);}
return result;}
disconnect(elementId){this.logger('[MudBlazor | ResizeObserver] Try to unobserve element with id',{elementId});var affectedObservedElement=this._observervedElements.find((x)=>x.id==elementId);if(affectedObservedElement){var element=affectedObservedElement.element;this._resizeObserver.unobserve(element);this.logger('[MudBlazor | ResizeObserver] Element found. Ubobserving size changes of element',{element});var index=this._observervedElements.indexOf(affectedObservedElement);this._observervedElements.splice(index,1);}}
cancelListener(){this.logger('[MudBlazor | ResizeObserver] Closing ResizeObserver. Detaching all observed elements');this._resizeObserver.disconnect();this._dotNetRef=undefined;}}
window.mudResizeObserver=new MudResizeObserverFactory();class MudInput{resetValue(id){const input=document.getElementById(id);if(input){input.value='';}}}
window.mudInput=new MudInput();class MudKeyInterceptorFactory{connect(dotNetRef,elementId,options){if(!elementId)
throw"elementId: expected element id!";var element=document.getElementById(elementId);if(!element) throw"elementId: expected element id!";var element=document.getElementById(elementId);if(!element)
throw"no element found for id: "+elementId;if(!element.mudKeyInterceptor) throw"no element found for id: "+elementId;if(!element.mudKeyInterceptor)
element.mudKeyInterceptor=new MudKeyInterceptor(dotNetRef,options);element.mudKeyInterceptor.connect(element);} element.mudKeyInterceptor=new MudKeyInterceptor(dotNetRef,options);element.mudKeyInterceptor.connect(element);}
@@ -59,69 +76,86 @@ processKeyUp(args,keyOptions){if(this.matchesKeyCombination(keyOptions.preventUp
args.preventDefault();if(this.matchesKeyCombination(keyOptions.stopUp,args)) args.preventDefault();if(this.matchesKeyCombination(keyOptions.stopUp,args))
args.stopPropagation();} args.stopPropagation();}
toKeyboardEventArgs(args){return{Key:args.key,Code:args.code,Location:args.location,Repeat:args.repeat,CtrlKey:args.ctrlKey,ShiftKey:args.shiftKey,AltKey:args.altKey,MetaKey:args.metaKey};}} toKeyboardEventArgs(args){return{Key:args.key,Code:args.code,Location:args.location,Repeat:args.repeat,CtrlKey:args.ctrlKey,ShiftKey:args.shiftKey,AltKey:args.altKey,MetaKey:args.metaKey};}}
class MudThrottledEventManager{constructor(){this.mapper={};} class MudElementReference{constructor(){this.listenerId=0;this.eventListeners={};}
subscribe(eventName,elementId,projection,throotleInterval,key,properties,dotnetReference){const handlerRef=this.throttleEventHandler.bind(this,key);let elem=document.getElementById(elementId);if(elem){elem.addEventListener(eventName,handlerRef,false);let projector=null;if(projection){const parts=projection.split('.');let functionPointer=window;let functionReferenceFound=true;if(parts.length==0||parts.length==1){functionPointer=functionPointer[projection];} focus(element){if(element)
else{for(let i=0;i<parts.length;i++){functionPointer=functionPointer[parts[i]];if(!functionPointer){functionReferenceFound=false;break;}}} {element.focus();}}
if(functionReferenceFound===true){projector=functionPointer;}} blur(element){if(element){element.blur();}}
this.mapper[key]={eventName:eventName,handler:handlerRef,delay:throotleInterval,timerId:-1,reference:dotnetReference,elementId:elementId,properties:properties,projection:projector,};}} focusFirst(element,skip=0,min=0){if(element)
subscribeGlobal(eventName,throotleInterval,key,properties,dotnetReference){let handlerRef=throotleInterval>0?this.throttleEventHandler.bind(this,key):this.eventHandler.bind(this,key);document.addEventListener(eventName,handlerRef,false);this.mapper[key]={eventName:eventName,handler:handlerRef,delay:throotleInterval,timerId:-1,reference:dotnetReference,elementId:document,properties:properties,projection:null,};} {let tabbables=getTabbableElements(element);if(tabbables.length<=min)
throttleEventHandler(key,event){const entry=this.mapper[key];if(!entry){return;} element.focus();else
clearTimeout(entry.timerId);entry.timerId=window.setTimeout(this.eventHandler.bind(this,key,event),entry.delay);} tabbables[skip].focus();}}
eventHandler(key,event){const entry=this.mapper[key];if(!entry){return;} focusLast(element,skip=0,min=0){if(element)
var elem=document.getElementById(entry.elementId);if(elem!=event.srcElement&&entry.elementId!=document){return;} {let tabbables=getTabbableElements(element);if(tabbables.length<=min)
const eventEntry={};for(var i=0;i<entry.properties.length;i++){eventEntry[entry.properties[i]]=event[entry.properties[i]];} element.focus();else
if(entry.projection){if(typeof entry.projection==="function"){entry.projection.apply(null,[eventEntry,event]);}} tabbables[tabbables.length-skip-1].focus();}}
entry.reference.invokeMethodAsync('OnEventOccur',key,JSON.stringify(eventEntry));} saveFocus(element){if(element)
unsubscribe(key){const entry=this.mapper[key];if(!entry){return;} {element['mudblazor_savedFocus']=document.activeElement;}}
entry.reference=null;if(document==entry.elementId){document.removeEventListener(entry.eventName,entry.handler,false);}else{const elem=document.getElementById(entry.elementId);if(elem){elem.removeEventListener(entry.eventName,entry.handler,false);}} restoreFocus(element){if(element)
delete this.mapper[key];}};window.mudThrottledEventManager=new MudThrottledEventManager();window.mudEventProjections={correctOffset:function(eventEntry,event){var target=event.target.getBoundingClientRect();eventEntry.offsetX=event.clientX-target.x;eventEntry.offsetY=event.clientY-target.y;}};class MudJsEventFactory{connect(dotNetRef,elementId,options){if(!elementId) {let previous=element['mudblazor_savedFocus'];delete element['mudblazor_savedFocus']
throw"[MudBlazor | JsEvent] elementId: expected element id!";var element=document.getElementById(elementId);if(!element) if(previous)
throw"[MudBlazor | JsEvent] no element found for id: "+elementId;if(!element.mudJsEvent) previous.focus();}}
element.mudJsEvent=new MudJsEvent(dotNetRef,options);element.mudJsEvent.connect(element);} selectRange(element,pos1,pos2){if(element)
disconnect(elementId){var element=document.getElementById(elementId);if(!element||!element.mudJsEvent) {if(element.createTextRange){let selRange=element.createTextRange();selRange.collapse(true);selRange.moveStart('character',pos1);selRange.moveEnd('character',pos2);selRange.select();}else if(element.setSelectionRange){element.setSelectionRange(pos1,pos2);}else if(element.selectionStart){element.selectionStart=pos1;element.selectionEnd=pos2;}
return;element.mudJsEvent.disconnect();} element.focus();}}
subscribe(elementId,eventName){if(!elementId) select(element){if(element)
throw"[MudBlazor | JsEvent] elementId: expected element id!";var element=document.getElementById(elementId);if(!element) {element.select();}}
throw"[MudBlazor | JsEvent] no element found for id: "+elementId;if(!element.mudJsEvent) getBoundingClientRect(element){if(!element)return;var rect=JSON.parse(JSON.stringify(element.getBoundingClientRect()));rect.scrollY=window.scrollY||document.documentElement.scrollTop;rect.scrollX=window.scrollX||document.documentElement.scrollLeft;rect.windowHeight=window.innerHeight;rect.windowWidth=window.innerWidth;return rect;}
throw"[MudBlazor | JsEvent] please connect before subscribing" changeCss(element,css){if(element)
element.mudJsEvent.subscribe(eventName);} {element.className=css;}}
unsubscribe(elementId,eventName){var element=document.getElementById(elementId);if(!element||!element.mudJsEvent) removeEventListener(element,event,eventId){element.removeEventListener(event,this.eventListeners[eventId]);delete this.eventListeners[eventId];}
return;element.mudJsEvent.unsubscribe(element,eventName);}} addDefaultPreventingHandler(element,eventName){let listener=function(e){e.preventDefault();}
window.mudJsEvent=new MudJsEventFactory();class MudJsEvent{constructor(dotNetRef,options){this._dotNetRef=dotNetRef;this._options=options||{};this.logger=options.enableLogging?console.log:(message)=>{};this.logger('[MudBlazor | JsEvent] Initialized',{options});this._subscribedEvents={};} element.addEventListener(eventName,listener,{passive:false});this.eventListeners[++this.listenerId]=listener;return this.listenerId;}
connect(element){if(!this._options) removeDefaultPreventingHandler(element,eventName,listenerId){this.removeEventListener(element,eventName,listenerId);}
return;if(!this._options.targetClass) addDefaultPreventingHandlers(element,eventNames){let listeners=[];for(const eventName of eventNames){let listenerId=this.addDefaultPreventingHandler(element,eventName);listeners.push(listenerId);}
throw"_options.targetClass: css class name expected";if(this._observer){return;} return listeners;}
var targetClass=this._options.targetClass;this.logger('[MudBlazor | JsEvent] Start observing DOM of element for changes to child with class ',{element,targetClass});this._element=element;this._observer=new MutationObserver(this.onDomChanged);this._observer.mudJsEvent=this;this._observer.observe(this._element,{attributes:false,childList:true,subtree:true});this._observedChildren=[];} removeDefaultPreventingHandlers(element,eventNames,listenerIds){for(let index=0;index<eventNames.length;++index){const eventName=eventNames[index];const listenerId=listenerIds[index];this.removeDefaultPreventingHandler(element,eventName,listenerId);}}};window.mudElementRef=new MudElementReference();const darkThemeMediaQuery=window.matchMedia("(prefers-color-scheme: dark)");window.darkModeChange=()=>{return darkThemeMediaQuery.matches;};function darkModeChangeListener(e){dotNetHelperTheme.invokeMethodAsync('SystemPreferenceChanged',e.matches);}
disconnect(){if(!this._observer) function watchDarkThemeMedia(dotNetHelper){dotNetHelperTheme=dotNetHelper;darkThemeMediaQuery.addEventListener('change',darkModeChangeListener);}
return;this.logger('[MudBlazor | JsEvent] disconnect mutation observer and event handler ');this._observer.disconnect();this._observer=null;for(const child of this._observedChildren) function stopWatchingDarkThemeMedia(){darkThemeMediaQuery.removeEventListener('change',darkModeChangeListener);}
this.detachHandlers(child);} class MudScrollSpy{constructor(){this.lastKnowElement=null;this.handlerRef=null;}
subscribe(eventName){if(this._subscribedEvents[eventName]){return;} spying(dotnetReference,containerSelector,sectionClassSelector){this.lastKnowElement=null;this.handlerRef=this.handleScroll.bind(this,dotnetReference,containerSelector,sectionClassSelector);document.addEventListener('scroll',this.handlerRef,true);window.addEventListener('resize',this.handlerRef,true);}
var element=this._element;var targetClass=this._options.targetClass;this._subscribedEvents[eventName]=true;for(const child of element.getElementsByClassName(targetClass)){this.attachHandlers(child);}} handleScroll(dotnetReference,containerSelector,sectionClassSelector,event){const container=document.querySelector(containerSelector);if(container===null){return;}
unsubscribe(eventName){if(!this._observer) const elements=document.getElementsByClassName(sectionClassSelector);if(elements.length===0){return;}
return;this.logger('[MudBlazor | JsEvent] unsubscribe event handler '+eventName);this._observer.disconnect();this._observer=null;this._subscribedEvents[eventName]=false;for(const child of this._observedChildren){this.detachHandler(child,eventName);}} const containerTop=container.tagName==='HTML'?0:container.getBoundingClientRect().top;const containerHeight=container.clientHeight;const center=containerTop+containerHeight/2.0;let minDifference=Number.MAX_SAFE_INTEGER;let foundAbove=false;let elementId='';for(let i=0;i<elements.length;i++){const element=elements[i];const rect=element.getBoundingClientRect();const diff=Math.abs(rect.top-center);if(!foundAbove&&rect.top<center){foundAbove=true;minDifference=diff;elementId=element.id;continue;}
attachHandlers(child){child.mudJsEvent=this;for(var eventName of Object.getOwnPropertyNames(this._subscribedEvents)){if(!this._subscribedEvents[eventName]) if(foundAbove&&rect.top>=center){continue;}
continue;this.logger('[MudBlazor | JsEvent] attaching event '+eventName,child);child.addEventListener(eventName,this.eventHandler);} if(diff<minDifference){minDifference=diff;elementId=element.id;}}
if(this._observedChildren.indexOf(child)<0) if(elementId!==this.lastKnowElement){this.lastKnowElement=elementId;history.replaceState(null,'',window.location.pathname+"#"+elementId);dotnetReference.invokeMethodAsync('SectionChangeOccured',elementId);}}
this._observedChildren.push(child);} activateSection(sectionId){const element=document.getElementById(sectionId);if(element){this.lastKnowElement=sectionId;history.replaceState(null,'',window.location.pathname+"#"+sectionId);}}
detachHandler(child,eventName){this.logger('[MudBlazor | JsEvent] detaching handler '+eventName,child);child.removeEventListener(eventName,this.eventHandler);} scrollToSection(sectionId){if(sectionId){let element=document.getElementById(sectionId);if(element){element.scrollIntoView({behavior:'smooth',block:'center',inline:'start'});}}
detachHandlers(child){this.logger('[MudBlazor | JsEvent] detaching handlers ',child);for(var eventName of Object.getOwnPropertyNames(this._subscribedEvents)){if(!this._subscribedEvents[eventName]) else{window.scrollTo({top:0,behavior:'smooth'});}}
continue;child.removeEventListener(eventName,this.eventHandler);} unspy(){document.removeEventListener('scroll',this.handlerRef,true);window.removeEventListener('resize',this.handlerRef,true);}};window.mudScrollSpy=new MudScrollSpy();window.mudInputAutoGrow={initAutoGrow:(elem,maxLines)=>{const compStyle=getComputedStyle(elem);const lineHeight=parseFloat(compStyle.getPropertyValue('line-height'));let maxHeight=0;elem.updateParameters=function(newMaxLines){if(newMaxLines>0){maxHeight=lineHeight*newMaxLines;}else{maxHeight=0;}}
this._observedChildren=this._observedChildren.filter(x=>x!==child);} elem.adjustAutoGrowHeight=function(didReflow=false){const scrollTops=[];let curElem=elem;while(curElem&&curElem.parentNode&&curElem.parentNode instanceof Element){if(curElem.parentNode.scrollTop){scrollTops.push([curElem.parentNode,curElem.parentNode.scrollTop]);}
onDomChanged(mutationsList,observer){var self=this.mudJsEvent;var targetClass=self._options.targetClass;for(const mutation of mutationsList){for(const element of mutation.addedNodes){if(element.classList&&element.classList.contains(targetClass)){if(!self._options.TagName||element.tagName==self._options.TagName) curElem=curElem.parentNode;}
self.attachHandlers(element);}} elem.style.height=0;if(didReflow){elem.style.textAlign=null;}
for(const element of mutation.removedNodes){if(element.classList&&element.classList.contains(targetClass)){if(!self._options.tagName||element.tagName==self._options.tagName) let minHeight=lineHeight*elem.rows;let newHeight=Math.max(minHeight,elem.scrollHeight);let initialOverflowY=elem.style.overflowY;if(maxHeight>0&&newHeight>maxHeight){elem.style.overflowY='auto';newHeight=maxHeight;}else{elem.style.overflowY='hidden';}
self.detachHandlers(element);}}}} elem.style.height=newHeight+"px";scrollTops.forEach(([node,scrollTop])=>{node.style.scrollBehavior='auto';node.scrollTop=scrollTop;node.style.scrollBehavior=null;});if(!didReflow&&initialOverflowY!==elem.style.overflowY&&elem.style.overflowY==='hidden'){elem.style.textAlign='end';elem.adjustAutoGrowHeight(true);}}
eventHandler(e){var self=this.mudJsEvent;var eventName=e.type;self.logger('[MudBlazor | JsEvent] "'+eventName+'"',e);self["on"+eventName](self,e);} elem.restoreToInitialState=function(){elem.removeEventListener('input',elem.adjustAutoGrowHeight);elem.style.overflowY=null;elem.style.height=null;}
onkeyup(self,e){const caretPosition=e.target.selectionStart;const invoke=self._subscribedEvents["keyup"];if(invoke){self._dotNetRef.invokeMethodAsync('OnCaretPositionChanged',caretPosition);}} elem.addEventListener('input',elem.adjustAutoGrowHeight);window.addEventListener('resize',elem.adjustAutoGrowHeight);elem.updateParameters(maxLines);elem.adjustAutoGrowHeight();},adjustHeight:(elem)=>{if(typeof elem.adjustAutoGrowHeight==='function'){elem.adjustAutoGrowHeight();}},updateParams:(elem,maxLines)=>{if(typeof elem.updateParameters==='function'){elem.updateParameters(maxLines);}
onclick(self,e){const caretPosition=e.target.selectionStart;const invoke=self._subscribedEvents["click"];if(invoke){self._dotNetRef.invokeMethodAsync('OnCaretPositionChanged',caretPosition);}} if(typeof elem.adjustAutoGrowHeight==='function'){elem.adjustAutoGrowHeight();}},destroy:(elem)=>{window.removeEventListener('resize',elem.adjustAutoGrowHeight);if(typeof elem.restoreToInitialState==='function'){elem.restoreToInitialState();}}}
onpaste(self,e){const invoke=self._subscribedEvents["paste"];if(invoke){e.preventDefault();e.stopPropagation();const text=(e.originalEvent||e).clipboardData.getData('text/plain');self._dotNetRef.invokeMethodAsync('OnPaste',text);}} window.mudTimePicker={initPointerEvents:(clock,dotNetHelper)=>{let isPointerDown=false;const startHandler=(event)=>{if(event.button!==0){return;}
onselect(self,e){const invoke=self._subscribedEvents["select"];if(invoke){const start=e.target.selectionStart;const end=e.target.selectionEnd;if(start===end) isPointerDown=true;event.target.releasePointerCapture(event.pointerId);if(event.target.classList.contains('mud-hour')||event.target.classList.contains('mud-minute')){let attributeValue=event.target.getAttribute('data-stick-value');let stickValue=attributeValue?parseInt(attributeValue):-1;dotNetHelper.invokeMethodAsync('SelectTimeFromStick',stickValue,false);}
return;self._dotNetRef.invokeMethodAsync('OnSelect',start,end);}}} event.preventDefault();};const endHandler=(event)=>{if(event.button!==0){return;}
class MudResizeListener{constructor(id){this.logger=function(message){};this.options={};this.throttleResizeHandlerId=-1;this.dotnet=undefined;this.breakpoint=-1;this.id=id;this.handleResize=this.throttleResizeHandler.bind(this);} isPointerDown=false;if(event.target.classList.contains('mud-hour')||event.target.classList.contains('mud-minute')){let attributeValue=event.target.getAttribute('data-stick-value');let stickValue=attributeValue?parseInt(attributeValue):-1;dotNetHelper.invokeMethodAsync('OnStickClick',stickValue);}
event.preventDefault();};const moveHandler=(event)=>{if(!isPointerDown||(!event.target.classList.contains('mud-hour')&&!event.target.classList.contains('mud-minute'))){return;}
let attributeValue=event.target.getAttribute('data-stick-value');let stickValue=attributeValue?parseInt(attributeValue):-1;dotNetHelper.invokeMethodAsync('SelectTimeFromStick',stickValue,true);event.preventDefault();};clock.addEventListener('pointerdown',startHandler);clock.addEventListener('pointerup',endHandler);clock.addEventListener('pointercancel',endHandler);clock.addEventListener('pointerover',moveHandler);clock.destroy=()=>{clock.removeEventListener('pointerdown',startHandler);clock.removeEventListener('pointerup',endHandler);clock.removeEventListener('pointercancel',endHandler);clock.removeEventListener('pointerover',moveHandler);};},destroyPointerEvents:(container)=>{if(typeof container.destroy==='function'){container.destroy();}}};class MudScrollListener{constructor(){this.throttleScrollHandlerId=-1;this.handlerRef=null;}
listenForScroll(dotnetReference,selector){let element=selector?document.querySelector(selector):document;this.handlerRef=this.throttleScrollHandler.bind(this,dotnetReference);element.addEventListener('scroll',this.handlerRef,false);}
throttleScrollHandler(dotnetReference,event){clearTimeout(this.throttleScrollHandlerId);this.throttleScrollHandlerId=window.setTimeout(this.scrollHandler.bind(this,dotnetReference,event),100);}
scrollHandler(dotnetReference,event){try{let element=event.target;let scrollTop=element.scrollTop;let scrollHeight=element.scrollHeight;let scrollWidth=element.scrollWidth;let scrollLeft=element.scrollLeft;let nodeName=element.nodeName;let firstChild=element.firstElementChild;let firstChildBoundingClientRect=firstChild.getBoundingClientRect();dotnetReference.invokeMethodAsync('RaiseOnScroll',{firstChildBoundingClientRect,scrollLeft,scrollTop,scrollHeight,scrollWidth,nodeName,});}catch(error){console.log('[MudBlazor] Error in scrollHandler:',{error});}}
cancelListener(selector){let element=selector?document.querySelector(selector):document;element.removeEventListener('scroll',this.handlerRef);}};window.mudScrollListener=new MudScrollListener();window.mudDragAndDrop={initDropZone:(id)=>{const elem=document.getElementById('mud-drop-zone-'+id);elem.addEventListener('dragover',()=>event.preventDefault());elem.addEventListener('dragstart',()=>event.dataTransfer.setData('',event.target.id));},makeDropZonesNotRelative:()=>{var firstDropItems=Array.from(document.getElementsByClassName('mud-drop-item')).filter(x=>x.getAttribute('index')=="-1");for(let dropItem of firstDropItems){dropItem.style.position='static';}
const dropZones=document.getElementsByClassName('mud-drop-zone');for(let dropZone of dropZones){dropZone.style.position='unset';}},getDropZoneIdentifierOnPosition:(x,y)=>{const elems=document.elementsFromPoint(x,y);const dropZones=elems.filter(e=>e.classList.contains('mud-drop-zone'))
const dropZone=dropZones[0];if(dropZone){return dropZone.getAttribute('identifier')||"";}
return"";},getDropIndexOnPosition:(x,y,id)=>{const elems=document.elementsFromPoint(x,y);const dropItems=elems.filter(e=>e.classList.contains('mud-drop-item')&&e.id!=('mud-drop-item-'+id))
const dropItem=dropItems[0];if(dropItem){return dropItem.getAttribute('index')||"";}
return"";},makeDropZonesRelative:()=>{const dropZones=document.getElementsByClassName('mud-drop-zone');for(let dropZone of dropZones){dropZone.style.position='relative';}
var firstDropItems=Array.from(document.getElementsByClassName('mud-drop-item')).filter(x=>x.getAttribute('index')=="-1");for(let dropItem of firstDropItems){dropItem.style.position='relative';}},moveItemByDifference:(id,dx,dy)=>{const elem=document.getElementById('mud-drop-item-'+id);var tx=(parseFloat(elem.getAttribute('data-x'))||0)+dx;var ty=(parseFloat(elem.getAttribute('data-y'))||0)+dy;elem.style.webkitTransform=elem.style.transform='translate3d('+tx+'px, '+ty+'px, 10px)';elem.setAttribute('data-x',tx);elem.setAttribute('data-y',ty);},resetItem:(id)=>{const elem=document.getElementById('mud-drop-item-'+id);if(elem){elem.style.webkitTransform=elem.style.transform='';elem.setAttribute('data-x',0);elem.setAttribute('data-y',0);}}};class MudWindow{copyToClipboard(text){navigator.clipboard.writeText(text);}
changeCssById(id,css){var element=document.getElementById(id);if(element){element.className=css;}}
updateStyleProperty(elementId,propertyName,value){const element=document.getElementById(elementId);if(element){element.style.setProperty(propertyName,value);}}
changeGlobalCssVariable(name,newValue){document.documentElement.style.setProperty(name,newValue);}
open(args){window.open(args);}}
window.mudWindow=new MudWindow();class MudResizeListener{constructor(id){this.logger=function(message){};this.options={};this.throttleResizeHandlerId=-1;this.dotnet=undefined;this.breakpoint=-1;this.id=id;this.handleResize=this.throttleResizeHandler.bind(this);}
listenForResize(dotnetRef,options){if(this.dotnet){this.options=options;return;} listenForResize(dotnetRef,options){if(this.dotnet){this.options=options;return;}
this.options=options;this.dotnet=dotnetRef;this.logger=options.enableLogging?console.log:(message)=>{};this.logger(`[MudBlazor]Reporting resize events at rate of:${(this.options||{}).reportRate||100}ms`);window.addEventListener("resize",this.handleResize,false);if(!this.options.suppressInitEvent){this.resizeHandler();} this.options=options;this.dotnet=dotnetRef;this.logger=options.enableLogging?console.log:(message)=>{};this.logger(`[MudBlazor]Reporting resize events at rate of:${this.options.reportRate}ms`);window.addEventListener("resize",this.handleResize,false);if(!this.options.suppressInitEvent){this.resizeHandler();}
this.breakpoint=this.getBreakpoint(window.innerWidth);} this.breakpoint=this.getBreakpoint(window.innerWidth);}
throttleResizeHandler(){clearTimeout(this.throttleResizeHandlerId);this.throttleResizeHandlerId=window.setTimeout(this.resizeHandler.bind(this),((this.options||{}).reportRate||100));} throttleResizeHandler(){clearTimeout(this.throttleResizeHandlerId);this.throttleResizeHandlerId=window.setTimeout(this.resizeHandler.bind(this),this.options.reportRate);}
resizeHandler(){if(this.options.notifyOnBreakpointOnly){let bp=this.getBreakpoint(window.innerWidth);if(bp==this.breakpoint){return;} resizeHandler(){if(this.options.notifyOnBreakpointOnly){let bp=this.getBreakpoint(window.innerWidth);if(bp==this.breakpoint){return;}
this.breakpoint=bp;} this.breakpoint=bp;}
try{if(this.id){this.dotnet.invokeMethodAsync('RaiseOnResized',{height:window.innerHeight,width:window.innerWidth},this.getBreakpoint(window.innerWidth),this.id);} try{if(this.id){this.dotnet.invokeMethodAsync('RaiseOnResized',{height:window.innerHeight,width:window.innerWidth},this.getBreakpoint(window.innerWidth),this.id);}
@@ -138,32 +172,7 @@ return 1;else
return 0;}};window.mudResizeListener=new MudResizeListener();window.mudResizeListenerFactory={mapping:{},listenForResize:(dotnetRef,options,id)=>{var map=window.mudResizeListenerFactory.mapping;if(map[id]){return;} return 0;}};window.mudResizeListener=new MudResizeListener();window.mudResizeListenerFactory={mapping:{},listenForResize:(dotnetRef,options,id)=>{var map=window.mudResizeListenerFactory.mapping;if(map[id]){return;}
var listener=new MudResizeListener(id);listener.listenForResize(dotnetRef,options);map[id]=listener;},cancelListener:(id)=>{var map=window.mudResizeListenerFactory.mapping;if(!map[id]){return;} var listener=new MudResizeListener(id);listener.listenForResize(dotnetRef,options);map[id]=listener;},cancelListener:(id)=>{var map=window.mudResizeListenerFactory.mapping;if(!map[id]){return;}
var listener=map[id];listener.cancelListener();delete map[id];},cancelListeners:(ids)=>{for(let i=0;i<ids.length;i++){window.mudResizeListenerFactory.cancelListener(ids[i]);}},dispose(){var map=window.mudResizeListenerFactory.mapping;for(var id in map){window.mudResizeListenerFactory.cancelListener(id);}}} var listener=map[id];listener.cancelListener();delete map[id];},cancelListeners:(ids)=>{for(let i=0;i<ids.length;i++){window.mudResizeListenerFactory.cancelListener(ids[i]);}},dispose(){var map=window.mudResizeListenerFactory.mapping;for(var id in map){window.mudResizeListenerFactory.cancelListener(id);}}}
const darkThemeMediaQuery=window.matchMedia("(prefers-color-scheme: dark)");window.darkModeChange=(dotNetHelper)=>{return darkThemeMediaQuery.matches;};function watchDarkThemeMedia(dotNetHelper){dotNetHelperTheme=dotNetHelper;window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change',function(e){dotNetHelperTheme.invokeMethodAsync('SystemPreferenceChanged',window.matchMedia("(prefers-color-scheme: dark)").matches);});}function setRippleOffset(event,target){const rect=target.getBoundingClientRect();const x=event.clientX-rect.left-rect.width/2;const y=event.clientY-rect.top-rect.height/2;target.style.setProperty("--mud-ripple-offset-x",`${x}px`);target.style.setProperty("--mud-ripple-offset-y",`${y}px`);} window.mudpopoverHelper={calculatePopoverPosition:function(list,boundingRect,selfRect){let top=0;let left=0;if(list.indexOf('mud-popover-anchor-top-left')>=0){left=boundingRect.left;top=boundingRect.top;}else if(list.indexOf('mud-popover-anchor-top-center')>=0){left=boundingRect.left+boundingRect.width/2;top=boundingRect.top;}else if(list.indexOf('mud-popover-anchor-top-right')>=0){left=boundingRect.left+boundingRect.width;top=boundingRect.top;}else if(list.indexOf('mud-popover-anchor-center-left')>=0){left=boundingRect.left;top=boundingRect.top+boundingRect.height/2;}else if(list.indexOf('mud-popover-anchor-center-center')>=0){left=boundingRect.left+boundingRect.width/2;top=boundingRect.top+boundingRect.height/2;}else if(list.indexOf('mud-popover-anchor-center-right')>=0){left=boundingRect.left+boundingRect.width;top=boundingRect.top+boundingRect.height/2;}else if(list.indexOf('mud-popover-anchor-bottom-left')>=0){left=boundingRect.left;top=boundingRect.top+boundingRect.height;}else if(list.indexOf('mud-popover-anchor-bottom-center')>=0){left=boundingRect.left+boundingRect.width/2;top=boundingRect.top+boundingRect.height;}else if(list.indexOf('mud-popover-anchor-bottom-right')>=0){left=boundingRect.left+boundingRect.width;top=boundingRect.top+boundingRect.height;}
document.addEventListener("click",function(event){const target=event.target.closest(".mud-ripple");if(target){setRippleOffset(event,target);}});class MudResizeObserverFactory{constructor(){this._maps={};}
connect(id,dotNetRef,elements,elementIds,options){var existingEntry=this._maps[id];if(!existingEntry){var observer=new MudResizeObserver(dotNetRef,options);this._maps[id]=observer;}
var result=this._maps[id].connect(elements,elementIds);return result;}
disconnect(id,element){var existingEntry=this._maps[id];if(existingEntry){existingEntry.disconnect(element);}}
cancelListener(id){var existingEntry=this._maps[id];if(existingEntry){existingEntry.cancelListener();delete this._maps[id];}}}
class MudResizeObserver{constructor(dotNetRef,options){this.logger=options.enableLogging?console.log:(message)=>{};this.options=options;this._dotNetRef=dotNetRef
var delay=(this.options||{}).reportRate||200;this.throttleResizeHandlerId=-1;var observervedElements=[];this._observervedElements=observervedElements;this.logger('[MudBlazor | ResizeObserver] Observer initialized');this._resizeObserver=new ResizeObserver(entries=>{var changes=[];this.logger('[MudBlazor | ResizeObserver] changes detected');for(let entry of entries){var target=entry.target;var affectedObservedElement=observervedElements.find((x)=>x.element==target);if(affectedObservedElement){var size=entry.target.getBoundingClientRect();if(affectedObservedElement.isInitialized==true){changes.push({id:affectedObservedElement.id,size:size});}
else{affectedObservedElement.isInitialized=true;}}}
if(changes.length>0){if(this.throttleResizeHandlerId>=0){clearTimeout(this.throttleResizeHandlerId);}
this.throttleResizeHandlerId=window.setTimeout(this.resizeHandler.bind(this,changes),delay);}});}
resizeHandler(changes){try{this.logger("[MudBlazor | ResizeObserver] OnSizeChanged handler invoked");this._dotNetRef.invokeMethodAsync("OnSizeChanged",changes);}catch(error){this.logger("[MudBlazor | ResizeObserver] Error in OnSizeChanged handler:",{error});}}
connect(elements,ids){var result=[];this.logger('[MudBlazor | ResizeObserver] Start observing elements...');for(var i=0;i<elements.length;i++){var newEntry={element:elements[i],id:ids[i],isInitialized:false,};this.logger("[MudBlazor | ResizeObserver] Start observing element:",{newEntry});result.push(elements[i].getBoundingClientRect());this._observervedElements.push(newEntry);this._resizeObserver.observe(elements[i]);}
return result;}
disconnect(elementId){this.logger('[MudBlazor | ResizeObserver] Try to unobserve element with id',{elementId});var affectedObservedElement=this._observervedElements.find((x)=>x.id==elementId);if(affectedObservedElement){var element=affectedObservedElement.element;this._resizeObserver.unobserve(element);this.logger('[MudBlazor | ResizeObserver] Element found. Ubobserving size changes of element',{element});var index=this._observervedElements.indexOf(affectedObservedElement);this._observervedElements.splice(index,1);}}
cancelListener(){this.logger('[MudBlazor | ResizeObserver] Closing ResizeObserver. Detaching all observed elements');this._resizeObserver.disconnect();this._dotNetRef=undefined;}}
window.mudResizeObserver=new MudResizeObserverFactory();class MudScrollManager{scrollToYear(elementId,offset){let element=document.getElementById(elementId);if(element){element.parentNode.scrollTop=element.offsetTop-element.parentNode.offsetTop-element.scrollHeight*3;}}
scrollToListItem(elementId){let element=document.getElementById(elementId);if(element){let parent=element.parentElement;if(parent){parent.scrollTop=element.offsetTop;}}}
scrollTo(selector,left,top,behavior){let element=document.querySelector(selector)||document.documentElement;element.scrollTo({left,top,behavior});}
scrollIntoView(selector,behavior){let element=document.querySelector(selector)||document.documentElement;if(element)
element.scrollIntoView({behavior,block:'center',inline:'start'});}
scrollToBottom(selector,behavior){let element=document.querySelector(selector);if(element)
element.scrollTop=element.scrollHeight;else
window.scrollTo(0,document.body.scrollHeight);}
lockScroll(selector,lockclass){let element=document.querySelector(selector)||document.body;let hasScrollBar=window.innerWidth>document.body.clientWidth;if(hasScrollBar){element.classList.add(lockclass);}else{let lockClassNoPadding=lockclass+"-no-padding";element.classList.add(lockClassNoPadding);}}
unlockScroll(selector,lockclass){let element=document.querySelector(selector)||document.body;element.classList.remove(lockclass);element.classList.remove(lockclass+"-no-padding");}};window.mudScrollManager=new MudScrollManager();window.mudpopoverHelper={calculatePopoverPosition:function(list,boundingRect,selfRect){let top=0;let left=0;if(list.indexOf('mud-popover-anchor-top-left')>=0){left=boundingRect.left;top=boundingRect.top;}else if(list.indexOf('mud-popover-anchor-top-center')>=0){left=boundingRect.left+boundingRect.width/2;top=boundingRect.top;}else if(list.indexOf('mud-popover-anchor-top-right')>=0){left=boundingRect.left+boundingRect.width;top=boundingRect.top;}else if(list.indexOf('mud-popover-anchor-center-left')>=0){left=boundingRect.left;top=boundingRect.top+boundingRect.height/2;}else if(list.indexOf('mud-popover-anchor-center-center')>=0){left=boundingRect.left+boundingRect.width/2;top=boundingRect.top+boundingRect.height/2;}else if(list.indexOf('mud-popover-anchor-center-right')>=0){left=boundingRect.left+boundingRect.width;top=boundingRect.top+boundingRect.height/2;}else if(list.indexOf('mud-popover-anchor-bottom-left')>=0){left=boundingRect.left;top=boundingRect.top+boundingRect.height;}else if(list.indexOf('mud-popover-anchor-bottom-center')>=0){left=boundingRect.left+boundingRect.width/2;top=boundingRect.top+boundingRect.height;}else if(list.indexOf('mud-popover-anchor-bottom-right')>=0){left=boundingRect.left+boundingRect.width;top=boundingRect.top+boundingRect.height;}
let offsetX=0;let offsetY=0;if(list.indexOf('mud-popover-top-left')>=0){offsetX=0;offsetY=0;}else if(list.indexOf('mud-popover-top-center')>=0){offsetX=-selfRect.width/2;offsetY=0;}else if(list.indexOf('mud-popover-top-right')>=0){offsetX=-selfRect.width;offsetY=0;} let offsetX=0;let offsetY=0;if(list.indexOf('mud-popover-top-left')>=0){offsetX=0;offsetY=0;}else if(list.indexOf('mud-popover-top-center')>=0){offsetX=-selfRect.width/2;offsetY=0;}else if(list.indexOf('mud-popover-top-right')>=0){offsetX=-selfRect.width;offsetY=0;}
else if(list.indexOf('mud-popover-center-left')>=0){offsetX=0;offsetY=-selfRect.height/2;}else if(list.indexOf('mud-popover-center-center')>=0){offsetX=-selfRect.width/2;offsetY=-selfRect.height/2;}else if(list.indexOf('mud-popover-center-right')>=0){offsetX=-selfRect.width;offsetY=-selfRect.height/2;} else if(list.indexOf('mud-popover-center-left')>=0){offsetX=0;offsetY=-selfRect.height/2;}else if(list.indexOf('mud-popover-center-center')>=0){offsetX=-selfRect.width/2;offsetY=-selfRect.height/2;}else if(list.indexOf('mud-popover-center-right')>=0){offsetX=-selfRect.width;offsetY=-selfRect.height/2;}
else if(list.indexOf('mud-popover-bottom-left')>=0){offsetX=0;offsetY=-selfRect.height;}else if(list.indexOf('mud-popover-bottom-center')>=0){offsetX=-selfRect.width/2;offsetY=-selfRect.height;}else if(list.indexOf('mud-popover-bottom-right')>=0){offsetX=-selfRect.width;offsetY=-selfRect.height;} else if(list.indexOf('mud-popover-bottom-left')>=0){offsetX=0;offsetY=-selfRect.height;}else if(list.indexOf('mud-popover-bottom-center')>=0){offsetX=-selfRect.width/2;offsetY=-selfRect.height;}else if(list.indexOf('mud-popover-bottom-right')>=0){offsetX=-selfRect.width;offsetY=-selfRect.height;}
@@ -207,72 +216,72 @@ dispose(){for(var i in this.map){disconnect(i);}
this.contentObserver.disconnect();this.contentObserver=null;} this.contentObserver.disconnect();this.contentObserver=null;}
getAllObservedContainers(){const result=[];for(var i in this.map){result.push(i);} getAllObservedContainers(){const result=[];for(var i in this.map){result.push(i);}
return result;}} return result;}}
window.mudPopover=new MudPopover();window.addEventListener('scroll',()=>{window.mudpopoverHelper.placePopoverByClassSelector('mud-popover-fixed');window.mudpopoverHelper.placePopoverByClassSelector('mud-popover-overflow-flip-always');});window.addEventListener('resize',()=>{window.mudpopoverHelper.placePopoverByClassSelector();});window.mudInputAutoGrow={initAutoGrow:(elem,maxLines)=>{const compStyle=getComputedStyle(elem);const lineHeight=parseFloat(compStyle.getPropertyValue('line-height'));let maxHeight=0;elem.updateParameters=function(newMaxLines){if(newMaxLines>0){maxHeight=lineHeight*newMaxLines;}else{maxHeight=0;}} window.mudPopover=new MudPopover();window.addEventListener('scroll',()=>{window.mudpopoverHelper.placePopoverByClassSelector('mud-popover-fixed');window.mudpopoverHelper.placePopoverByClassSelector('mud-popover-overflow-flip-always');});window.addEventListener('resize',()=>{window.mudpopoverHelper.placePopoverByClassSelector();});class MudFileUpload{openFilePicker(id){const element=document.getElementById(id);if(!element){return;}
elem.adjustAutoGrowHeight=function(didReflow=false){const scrollTops=[];let curElem=elem;while(curElem&&curElem.parentNode&&curElem.parentNode instanceof Element){if(curElem.parentNode.scrollTop){scrollTops.push([curElem.parentNode,curElem.parentNode.scrollTop]);} try{element.showPicker();}catch(error){element.click();}}}
curElem=curElem.parentNode;} window.mudFileUpload=new MudFileUpload();function setRippleOffset(event,target){const rect=target.getBoundingClientRect();const x=event.clientX-rect.left-rect.width/2;const y=event.clientY-rect.top-rect.height/2;target.style.setProperty("--mud-ripple-offset-x",`${x}px`);target.style.setProperty("--mud-ripple-offset-y",`${y}px`);}
elem.style.height=0;if(didReflow){elem.style.textAlign=null;} document.addEventListener("click",function(event){const target=event.target.closest(".mud-ripple");if(target){setRippleOffset(event,target);}});class MudScrollManager{scrollToYear(elementId,offset){let element=document.getElementById(elementId);if(element){element.parentNode.scrollTop=element.offsetTop-element.parentNode.offsetTop-element.scrollHeight*3;}}
let minHeight=lineHeight*elem.rows;let newHeight=Math.max(minHeight,elem.scrollHeight);let initialOverflowY=elem.style.overflowY;if(maxHeight>0&&newHeight>maxHeight){elem.style.overflowY='auto';newHeight=maxHeight;}else{elem.style.overflowY='hidden';} scrollToListItem(elementId){let element=document.getElementById(elementId);if(element){let parent=element.parentElement;if(parent){parent.scrollTop=element.offsetTop;}}}
elem.style.height=newHeight+"px";scrollTops.forEach(([node,scrollTop])=>{node.style.scrollBehavior='auto';node.scrollTop=scrollTop;node.style.scrollBehavior=null;});if(!didReflow&&initialOverflowY!==elem.style.overflowY&&elem.style.overflowY==='hidden'){elem.style.textAlign='end';elem.adjustAutoGrowHeight(true);}} scrollTo(selector,left,top,behavior){let element=document.querySelector(selector)||document.documentElement;element.scrollTo({left,top,behavior});}
elem.restoreToInitialState=function(){elem.removeEventListener('input',elem.adjustAutoGrowHeight);elem.style.overflowY=null;elem.style.height=null;} scrollIntoView(selector,behavior){let element=document.querySelector(selector)||document.documentElement;if(element)
elem.addEventListener('input',elem.adjustAutoGrowHeight);window.addEventListener('resize',elem.adjustAutoGrowHeight);elem.updateParameters(maxLines);elem.adjustAutoGrowHeight();},adjustHeight:(elem)=>{if(typeof elem.adjustAutoGrowHeight==='function'){elem.adjustAutoGrowHeight();}},updateParams:(elem,maxLines)=>{if(typeof elem.updateParameters==='function'){elem.updateParameters(maxLines);} element.scrollIntoView({behavior,block:'center',inline:'start'});}
if(typeof elem.adjustAutoGrowHeight==='function'){elem.adjustAutoGrowHeight();}},destroy:(elem)=>{window.removeEventListener('resize',elem.adjustAutoGrowHeight);if(typeof elem.restoreToInitialState==='function'){elem.restoreToInitialState();}}} scrollToBottom(selector,behavior){let element=document.querySelector(selector);if(element){element.scrollTo({top:element.scrollHeight,behavior:behavior});}else{window.scrollTo({top:document.body.scrollHeight,behavior:behavior});}}
class MudWindow{copyToClipboard(text){navigator.clipboard.writeText(text);} lockScroll(selector,lockclass){let element=document.querySelector(selector)||document.body;let hasScrollBar=window.innerWidth>document.body.clientWidth;if(hasScrollBar){element.classList.add(lockclass);}else{let lockClassNoPadding=lockclass+"-no-padding";element.classList.add(lockClassNoPadding);}}
changeCssById(id,css){var element=document.getElementById(id);if(element){element.className=css;}} unlockScroll(selector,lockclass){let element=document.querySelector(selector)||document.body;element.classList.remove(lockclass);element.classList.remove(lockclass+"-no-padding");}};window.mudScrollManager=new MudScrollManager();class MudJsEventFactory{connect(dotNetRef,elementId,options){if(!elementId)
updateStyleProperty(elementId,propertyName,value){const element=document.getElementById(elementId);if(element){element.style.setProperty(propertyName,value);}} throw"[MudBlazor | JsEvent] elementId: expected element id!";var element=document.getElementById(elementId);if(!element)
changeGlobalCssVariable(name,newValue){document.documentElement.style.setProperty(name,newValue);} throw"[MudBlazor | JsEvent] no element found for id: "+elementId;if(!element.mudJsEvent)
open(args){window.open(args);}};window.mudWindow=new MudWindow();class MudElementReference{constructor(){this.listenerId=0;this.eventListeners={};} element.mudJsEvent=new MudJsEvent(dotNetRef,options);element.mudJsEvent.connect(element);}
focus(element){if(element) disconnect(elementId){var element=document.getElementById(elementId);if(!element||!element.mudJsEvent)
{element.focus();}} return;element.mudJsEvent.disconnect();}
blur(element){if(element){element.blur();}} subscribe(elementId,eventName){if(!elementId)
focusFirst(element,skip=0,min=0){if(element) throw"[MudBlazor | JsEvent] elementId: expected element id!";var element=document.getElementById(elementId);if(!element)
{let tabbables=getTabbableElements(element);if(tabbables.length<=min) throw"[MudBlazor | JsEvent] no element found for id: "+elementId;if(!element.mudJsEvent)
element.focus();else throw"[MudBlazor | JsEvent] please connect before subscribing"
tabbables[skip].focus();}} element.mudJsEvent.subscribe(eventName);}
focusLast(element,skip=0,min=0){if(element) unsubscribe(elementId,eventName){var element=document.getElementById(elementId);if(!element||!element.mudJsEvent)
{let tabbables=getTabbableElements(element);if(tabbables.length<=min) return;element.mudJsEvent.unsubscribe(element,eventName);}}
element.focus();else window.mudJsEvent=new MudJsEventFactory();class MudJsEvent{constructor(dotNetRef,options){this._dotNetRef=dotNetRef;this._options=options||{};this.logger=options.enableLogging?console.log:(message)=>{};this.logger('[MudBlazor | JsEvent] Initialized',{options});this._subscribedEvents={};}
tabbables[tabbables.length-skip-1].focus();}} connect(element){if(!this._options)
saveFocus(element){if(element) return;if(!this._options.targetClass)
{element['mudblazor_savedFocus']=document.activeElement;}} throw"_options.targetClass: css class name expected";if(this._observer){return;}
restoreFocus(element){if(element) var targetClass=this._options.targetClass;this.logger('[MudBlazor | JsEvent] Start observing DOM of element for changes to child with class ',{element,targetClass});this._element=element;this._observer=new MutationObserver(this.onDomChanged);this._observer.mudJsEvent=this;this._observer.observe(this._element,{attributes:false,childList:true,subtree:true});this._observedChildren=[];}
{let previous=element['mudblazor_savedFocus'];delete element['mudblazor_savedFocus'] disconnect(){if(!this._observer)
if(previous) return;this.logger('[MudBlazor | JsEvent] disconnect mutation observer and event handler ');this._observer.disconnect();this._observer=null;for(const child of this._observedChildren)
previous.focus();}} this.detachHandlers(child);}
selectRange(element,pos1,pos2){if(element) subscribe(eventName){if(this._subscribedEvents[eventName]){return;}
{if(element.createTextRange){let selRange=element.createTextRange();selRange.collapse(true);selRange.moveStart('character',pos1);selRange.moveEnd('character',pos2);selRange.select();}else if(element.setSelectionRange){element.setSelectionRange(pos1,pos2);}else if(element.selectionStart){element.selectionStart=pos1;element.selectionEnd=pos2;} var element=this._element;var targetClass=this._options.targetClass;this._subscribedEvents[eventName]=true;for(const child of element.getElementsByClassName(targetClass)){this.attachHandlers(child);}}
element.focus();}} unsubscribe(eventName){if(!this._observer)
select(element){if(element) return;this.logger('[MudBlazor | JsEvent] unsubscribe event handler '+eventName);this._observer.disconnect();this._observer=null;this._subscribedEvents[eventName]=false;for(const child of this._observedChildren){this.detachHandler(child,eventName);}}
{element.select();}} attachHandlers(child){child.mudJsEvent=this;for(var eventName of Object.getOwnPropertyNames(this._subscribedEvents)){if(!this._subscribedEvents[eventName])
getBoundingClientRect(element){if(!element)return;var rect=JSON.parse(JSON.stringify(element.getBoundingClientRect()));rect.scrollY=window.scrollY||document.documentElement.scrollTop;rect.scrollX=window.scrollX||document.documentElement.scrollLeft;rect.windowHeight=window.innerHeight;rect.windowWidth=window.innerWidth;return rect;} continue;this.logger('[MudBlazor | JsEvent] attaching event '+eventName,child);child.addEventListener(eventName,this.eventHandler);}
changeCss(element,css){if(element) if(this._observedChildren.indexOf(child)<0)
{element.className=css;}} this._observedChildren.push(child);}
removeEventListener(element,event,eventId){element.removeEventListener(event,this.eventListeners[eventId]);delete this.eventListeners[eventId];} detachHandler(child,eventName){this.logger('[MudBlazor | JsEvent] detaching handler '+eventName,child);child.removeEventListener(eventName,this.eventHandler);}
addDefaultPreventingHandler(element,eventName){let listener=function(e){e.preventDefault();} detachHandlers(child){this.logger('[MudBlazor | JsEvent] detaching handlers ',child);for(var eventName of Object.getOwnPropertyNames(this._subscribedEvents)){if(!this._subscribedEvents[eventName])
element.addEventListener(eventName,listener,{passive:false});this.eventListeners[++this.listenerId]=listener;return this.listenerId;} continue;child.removeEventListener(eventName,this.eventHandler);}
removeDefaultPreventingHandler(element,eventName,listenerId){this.removeEventListener(element,eventName,listenerId);} this._observedChildren=this._observedChildren.filter(x=>x!==child);}
addDefaultPreventingHandlers(element,eventNames){let listeners=[];for(const eventName of eventNames){let listenerId=this.addDefaultPreventingHandler(element,eventName);listeners.push(listenerId);} onDomChanged(mutationsList,observer){var self=this.mudJsEvent;var targetClass=self._options.targetClass;for(const mutation of mutationsList){for(const element of mutation.addedNodes){if(element.classList&&element.classList.contains(targetClass)){if(!self._options.TagName||element.tagName==self._options.TagName)
return listeners;} self.attachHandlers(element);}}
removeDefaultPreventingHandlers(element,eventNames,listenerIds){for(let index=0;index<eventNames.length;++index){const eventName=eventNames[index];const listenerId=listenerIds[index];this.removeDefaultPreventingHandler(element,eventName,listenerId);}}};window.mudElementRef=new MudElementReference();class MudScrollSpy{constructor(){this.scrollToSectionRequested=null;this.lastKnowElement=null;this.handlerRef=null;} for(const element of mutation.removedNodes){if(element.classList&&element.classList.contains(targetClass)){if(!self._options.tagName||element.tagName==self._options.tagName)
spying(dotnetReference,selector){this.scrollToSectionRequested=null;this.lastKnowElement=null;this.handlerRef=this.handleScroll.bind(this,selector,dotnetReference);document.addEventListener('scroll',this.handlerRef,true);window.addEventListener('resize',this.handlerRef,true);} self.detachHandlers(element);}}}}
handleScroll(dotnetReference,selector,event){const elements=document.getElementsByClassName(selector);if(elements.length===0){return;} eventHandler(e){var self=this.mudJsEvent;var eventName=e.type;self.logger('[MudBlazor | JsEvent] "'+eventName+'"',e);self["on"+eventName](self,e);}
const center=window.innerHeight/2.0;let minDifference=Number.MAX_SAFE_INTEGER;let elementId='';for(let i=0;i<elements.length;i++){const element=elements[i];const rect=element.getBoundingClientRect();const diff=Math.abs(rect.top-center);if(diff<minDifference){minDifference=diff;elementId=element.id;}} onkeyup(self,e){const caretPosition=e.target.selectionStart;const invoke=self._subscribedEvents["keyup"];if(invoke){self._dotNetRef.invokeMethodAsync('OnCaretPositionChanged',caretPosition);}}
if(document.getElementById(elementId).getBoundingClientRect().top<window.innerHeight*0.8===false){return;} onclick(self,e){const caretPosition=e.target.selectionStart;const invoke=self._subscribedEvents["click"];if(invoke){self._dotNetRef.invokeMethodAsync('OnCaretPositionChanged',caretPosition);}}
if(this.scrollToSectionRequested!=null){if(this.scrollToSectionRequested==' '&&window.scrollY==0){this.scrollToSectionRequested=null;} onpaste(self,e){const invoke=self._subscribedEvents["paste"];if(invoke){e.preventDefault();e.stopPropagation();const text=(e.originalEvent||e).clipboardData.getData('text/plain');self._dotNetRef.invokeMethodAsync('OnPaste',text);}}
else{if(elementId===this.scrollToSectionRequested){this.scrollToSectionRequested=null;}} onselect(self,e){const invoke=self._subscribedEvents["select"];if(invoke){const start=e.target.selectionStart;const end=e.target.selectionEnd;if(start===end)
return;} return;self._dotNetRef.invokeMethodAsync('OnSelect',start,end);}}}
if(elementId!=this.lastKnowElement){this.lastKnowElement=elementId;history.replaceState(null,'',window.location.pathname+"#"+elementId);dotnetReference.invokeMethodAsync('SectionChangeOccured',elementId);}} class MudThrottledEventManager{constructor(){this.mapper={};}
activateSection(sectionId){const element=document.getElementById(sectionId);if(element){this.lastKnowElement=sectionId;history.replaceState(null,'',window.location.pathname+"#"+sectionId);}} subscribe(eventName,elementId,projection,throotleInterval,key,properties,dotnetReference){const handlerRef=this.throttleEventHandler.bind(this,key);let elem=document.getElementById(elementId);if(elem){elem.addEventListener(eventName,handlerRef,false);let projector=null;if(projection){const parts=projection.split('.');let functionPointer=window;let functionReferenceFound=true;if(parts.length==0||parts.length==1){functionPointer=functionPointer[projection];}
scrollToSection(sectionId){if(sectionId){let element=document.getElementById(sectionId);if(element){this.scrollToSectionRequested=sectionId;element.scrollIntoView({behavior:'smooth',block:'center',inline:'start'});}} else{for(let i=0;i<parts.length;i++){functionPointer=functionPointer[parts[i]];if(!functionPointer){functionReferenceFound=false;break;}}}
else{window.scrollTo({top:0,behavior:'smooth'});this.scrollToSectionRequested=' ';}} if(functionReferenceFound===true){projector=functionPointer;}}
unspy(){document.removeEventListener('scroll',this.handlerRef,true);window.removeEventListener('resize',this.handlerRef,true);}};window.mudScrollSpy=new MudScrollSpy();window.getTabbableElements=(element)=>{return element.querySelectorAll("a[href]:not([tabindex='-1']),"+"area[href]:not([tabindex='-1']),"+"button:not([disabled]):not([tabindex='-1']),"+"input:not([disabled]):not([tabindex='-1']):not([type='hidden']),"+"select:not([disabled]):not([tabindex='-1']),"+"textarea:not([disabled]):not([tabindex='-1']),"+"iframe:not([tabindex='-1']),"+"details:not([tabindex='-1']),"+"[tabindex]:not([tabindex='-1']),"+"[contentEditable=true]:not([tabindex='-1'])");};window.serializeParameter=(data,spec)=>{if(typeof data=="undefined"||data===null){return null;} this.mapper[key]={eventName:eventName,handler:handlerRef,delay:throotleInterval,timerId:-1,reference:dotnetReference,elementId:elementId,properties:properties,projection:projector,};}}
if(typeof data==="number"||typeof data==="string"||typeof data=="boolean"){return data;} subscribeGlobal(eventName,throotleInterval,key,properties,dotnetReference){let handlerRef=throotleInterval>0?this.throttleEventHandler.bind(this,key):this.eventHandler.bind(this,key);document.addEventListener(eventName,handlerRef,false);this.mapper[key]={eventName:eventName,handler:handlerRef,delay:throotleInterval,timerId:-1,reference:dotnetReference,elementId:document,properties:properties,projection:null,};}
let res=(Array.isArray(data))?[]:{};if(!spec){spec="*";} throttleEventHandler(key,event){const entry=this.mapper[key];if(!entry){return;}
for(let i in data){let currentMember=data[i];if(typeof currentMember==='function'||currentMember===null){continue;} clearTimeout(entry.timerId);entry.timerId=window.setTimeout(this.eventHandler.bind(this,key,event),entry.delay);}
let currentMemberSpec;if(spec!="*"){currentMemberSpec=Array.isArray(data)?spec:spec[i];if(!currentMemberSpec){continue;}}else{currentMemberSpec="*"} eventHandler(key,event){const entry=this.mapper[key];if(!entry){return;}
if(typeof currentMember==='object'){if(Array.isArray(currentMember)||currentMember.length){res[i]=[];for(let j=0;j<currentMember.length;j++){const arrayItem=currentMember[j];if(typeof arrayItem==='object'){res[i].push(this.serializeParameter(arrayItem,currentMemberSpec));}else{res[i].push(arrayItem);}}}else{if(currentMember.length===0){res[i]=[];}else{res[i]=this.serializeParameter(currentMember,currentMemberSpec);}}}else{if(currentMember===Infinity){currentMember="Infinity";} var elem=document.getElementById(entry.elementId);if(elem!=event.srcElement&&entry.elementId!=document){return;}
if(currentMember!==null){res[i]=currentMember;}}} const eventEntry={};for(var i=0;i<entry.properties.length;i++){eventEntry[entry.properties[i]]=event[entry.properties[i]];}
return res;};class MudScrollListener{constructor(){this.throttleScrollHandlerId=-1;this.handlerRef=null;} if(entry.projection){if(typeof entry.projection==="function"){entry.projection.apply(null,[eventEntry,event]);}}
listenForScroll(dotnetReference,selector){let element=selector?document.querySelector(selector):document;this.handlerRef=this.throttleScrollHandler.bind(this,dotnetReference);element.addEventListener('scroll',this.handlerRef,false);} entry.reference.invokeMethodAsync('OnEventOccur',key,JSON.stringify(eventEntry));}
throttleScrollHandler(dotnetReference,event){clearTimeout(this.throttleScrollHandlerId);this.throttleScrollHandlerId=window.setTimeout(this.scrollHandler.bind(this,dotnetReference,event),100);} unsubscribe(key){const entry=this.mapper[key];if(!entry){return;}
scrollHandler(dotnetReference,event){try{let element=event.target;let scrollTop=element.scrollTop;let scrollHeight=element.scrollHeight;let scrollWidth=element.scrollWidth;let scrollLeft=element.scrollLeft;let nodeName=element.nodeName;let firstChild=element.firstElementChild;let firstChildBoundingClientRect=firstChild.getBoundingClientRect();dotnetReference.invokeMethodAsync('RaiseOnScroll',{firstChildBoundingClientRect,scrollLeft,scrollTop,scrollHeight,scrollWidth,nodeName,});}catch(error){console.log('[MudBlazor] Error in scrollHandler:',{error});}} entry.reference=null;if(document==entry.elementId){document.removeEventListener(entry.eventName,entry.handler,false);}else{const elem=document.getElementById(entry.elementId);if(elem){elem.removeEventListener(entry.eventName,entry.handler,false);}}
cancelListener(selector){let element=selector?document.querySelector(selector):document;element.removeEventListener('scroll',this.handlerRef);}};window.mudScrollListener=new MudScrollListener(); delete this.mapper[key];}};window.mudThrottledEventManager=new MudThrottledEventManager();window.mudEventProjections={correctOffset:function(eventEntry,event){var target=event.target.getBoundingClientRect();eventEntry.offsetX=event.clientX-target.x;eventEntry.offsetY=event.clientY-target.y;}};
+6 -6
View File
@@ -1,9 +1,9 @@
0.8.3 0.8.5
2024-07-25 13:25:12 UTC 2024-07-28 16:44:01 UTC
165 167
8.0.107 (commit 1bdaef7265) 8.0.107 (commit 1bdaef7265)
8.0.7 (commit 2aade6beb0) 8.0.7 (commit 2aade6beb0)
1.79.0 (commit 129f3b996) 1.80.0 (commit 051478957)
7.4.0 7.4.0
1.6.1 1.7.1
72eb50d226f, release c1b92a05fc7, release
+640 -539
View File
File diff suppressed because it is too large. Load diff
+3 -3
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "mindwork-ai-studio" name = "mindwork-ai-studio"
version = "0.8.3" version = "0.8.5"
edition = "2021" edition = "2021"
description = "MindWork AI Studio" description = "MindWork AI Studio"
authors = ["Thorsten Sommer"] authors = ["Thorsten Sommer"]
@@ -9,13 +9,13 @@ authors = ["Thorsten Sommer"]
tauri-build = { version = "1.5", features = [] } tauri-build = { version = "1.5", features = [] }
[dependencies] [dependencies]
tauri = { version = "1.6", features = [ "updater", "http-all", "shell-sidecar", "path-all", "shell-open"] } tauri = { version = "1.7.1", features = [ "updater", "http-all", "shell-sidecar", "path-all", "shell-open"] }
tauri-plugin-window-state = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" } tauri-plugin-window-state = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" }
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" serde_json = "1.0"
keyring = "2" keyring = "2"
arboard = "3.4.0" arboard = "3.4.0"
tokio = "1.37.0" tokio = "1.39"
flexi_logger = "0.28" flexi_logger = "0.28"
log = "0.4" log = "0.4"
once_cell = "1.19.0" once_cell = "1.19.0"
+15 -1
View File
@@ -15,6 +15,7 @@ use tauri::api::process::{Command, CommandChild, CommandEvent};
use tauri::utils::config::AppUrl; use tauri::utils::config::AppUrl;
use tokio::time; use tokio::time;
use flexi_logger::{AdaptiveFormat, Logger}; use flexi_logger::{AdaptiveFormat, Logger};
use keyring::error::Error::NoEntry;
use log::{debug, error, info, warn}; use log::{debug, error, info, warn};
use tauri::updater::UpdateResponse; use tauri::updater::UpdateResponse;
@@ -292,7 +293,7 @@ enum ServerEvent {
} }
pub fn is_dev() -> bool { pub fn is_dev() -> bool {
cfg!(dev) cfg!(debug_assertions)
} }
pub fn is_prod() -> bool { pub fn is_prod() -> bool {
@@ -454,19 +455,31 @@ fn delete_secret(destination: String, user_name: String) -> DeleteSecretResponse
let service = format!("mindwork-ai-studio::{}", destination); let service = format!("mindwork-ai-studio::{}", destination);
let entry = Entry::new(service.as_str(), user_name.as_str()).unwrap(); let entry = Entry::new(service.as_str(), user_name.as_str()).unwrap();
let result = entry.delete_password(); let result = entry.delete_password();
match result { match result {
Ok(_) => { Ok(_) => {
warn!("Secret for {service} and user {user_name} was deleted successfully."); warn!("Secret for {service} and user {user_name} was deleted successfully.");
DeleteSecretResponse { DeleteSecretResponse {
success: true, success: true,
was_entry_found: true,
issue: String::from(""), issue: String::from(""),
} }
}, },
Err(NoEntry) => {
warn!("No secret for {service} and user {user_name} was found.");
DeleteSecretResponse {
success: true,
was_entry_found: false,
issue: String::from(""),
}
}
Err(e) => { Err(e) => {
error!("Failed to delete secret for {service} and user {user_name}: {e}."); error!("Failed to delete secret for {service} and user {user_name}: {e}.");
DeleteSecretResponse { DeleteSecretResponse {
success: false, success: false,
was_entry_found: false,
issue: e.to_string(), issue: e.to_string(),
} }
}, },
@@ -476,6 +489,7 @@ fn delete_secret(destination: String, user_name: String) -> DeleteSecretResponse
#[derive(Serialize)] #[derive(Serialize)]
struct DeleteSecretResponse { struct DeleteSecretResponse {
success: bool, success: bool,
was_entry_found: bool,
issue: String, issue: String,
} }
+1 -1
View File
@@ -6,7 +6,7 @@
}, },
"package": { "package": {
"productName": "MindWork AI Studio", "productName": "MindWork AI Studio",
"version": "0.8.3" "version": "0.8.5"
}, },
"tauri": { "tauri": {
"allowlist": { "allowlist": {