mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2025-02-05 14:49:06 +00:00
Migrate to MudBlazor v7.x.x (#41)
This commit is contained in:
parent
a956b55d6b
commit
5250e5d2fb
@ -20,7 +20,7 @@
|
||||
{
|
||||
<MudPaper Class="pr-2 mt-3" Outlined="@true">
|
||||
<MudText Typo="Typo.h6">Issues</MudText>
|
||||
<MudList Clickable="@true">
|
||||
<MudList T="string">
|
||||
@foreach (var issue in this.inputIssues)
|
||||
{
|
||||
<MudListItem Icon="@Icons.Material.Filled.Error" IconColor="Color.Error">
|
||||
|
@ -1,4 +1,4 @@
|
||||
<MudExpansionPanel Class="border-solid border rounded-lg" IsInitiallyExpanded="@this.IsExpanded">
|
||||
<MudExpansionPanel Class="border-solid border rounded-lg" Expanded="@this.IsExpanded">
|
||||
<TitleContent>
|
||||
<div class="d-flex align-center">
|
||||
<MudIcon Icon="@this.HeaderIcon" Size="@this.IconSize" Color="@this.IconColor" class="mr-3"/>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<MudList Clickable="@this.Clickable" Class="@this.Classes">
|
||||
<MudList T="string" ReadOnly="@(!this.Clickable)" Class="@this.Classes">
|
||||
@foreach(var item in this.Items)
|
||||
{
|
||||
<MudListItem Icon="@this.Icon" Style="display: flex; align-items: flex-start;">
|
||||
<MudListItem T="string" Icon="@this.Icon" Style="display: flex; align-items: flex-start;">
|
||||
<MudText Typo="Typo.body1" Style="text-align: justify; hyphens: auto;"><b>@item.Header:</b> @item.Text</MudText>
|
||||
</MudListItem>
|
||||
}
|
||||
|
@ -18,5 +18,5 @@ public class TreeItemData : ITreeItem
|
||||
|
||||
public bool Expandable { get; init; } = true;
|
||||
|
||||
public HashSet<ITreeItem> Children { get; init; } = [];
|
||||
public IReadOnlyCollection<TreeItemData<ITreeItem>> Children { get; init; } = [];
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
<MudTreeView T="ITreeItem" Items="@this.treeItems" MultiSelection="@false" Hover="@true" ExpandOnClick="@true">
|
||||
<MudTreeView T="ITreeItem" Items="@this.treeItems" SelectionMode="SelectionMode.SingleSelection" Hover="@true" ExpandOnClick="@true">
|
||||
<ItemTemplate Context="item">
|
||||
@switch (item)
|
||||
@switch (item.Value)
|
||||
{
|
||||
case TreeDivider:
|
||||
<li style="min-height: 1em;">
|
||||
@ -11,7 +11,7 @@
|
||||
case TreeItemData treeItem:
|
||||
@if (treeItem.Type is TreeItemType.CHAT)
|
||||
{
|
||||
<MudTreeViewItem T="ITreeItem" Icon="@treeItem.Icon" Value="@item" CanExpand="@treeItem.Expandable" Items="@treeItem.Children" OnClick="() => this.LoadChat(treeItem.Path, true)">
|
||||
<MudTreeViewItem T="ITreeItem" Icon="@treeItem.Icon" Value="@item.Value" CanExpand="@treeItem.Expandable" Items="@treeItem.Children" OnClick="() => this.LoadChat(treeItem.Path, true)">
|
||||
<BodyContent>
|
||||
<div style="display: grid; grid-template-columns: 1fr auto; align-items: center; width: 100%">
|
||||
<MudText Style="justify-self: start;">
|
||||
@ -44,7 +44,7 @@
|
||||
}
|
||||
else if (treeItem.Type is TreeItemType.WORKSPACE)
|
||||
{
|
||||
<MudTreeViewItem T="ITreeItem" Icon="@treeItem.Icon" Value="@item" CanExpand="@treeItem.Expandable" Items="@treeItem.Children">
|
||||
<MudTreeViewItem T="ITreeItem" Icon="@treeItem.Icon" Value="@item.Value" CanExpand="@treeItem.Expandable" Items="@treeItem.Children">
|
||||
<BodyContent>
|
||||
<div style="display: grid; grid-template-columns: 1fr auto; align-items: center; width: 100%">
|
||||
<MudText Style="justify-self: start;">@treeItem.Text</MudText>
|
||||
@ -63,7 +63,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
<MudTreeViewItem T="ITreeItem" Icon="@treeItem.Icon" Value="@item" CanExpand="@treeItem.Expandable" Items="@treeItem.Children">
|
||||
<MudTreeViewItem T="ITreeItem" Icon="@treeItem.Icon" Value="@item.Value" CanExpand="@treeItem.Expandable" Items="@treeItem.Children">
|
||||
<BodyContent>
|
||||
<div style="display: grid; grid-template-columns: 1fr auto; align-items: center; width: 100%">
|
||||
<MudText Style="justify-self: start;">@treeItem.Text</MudText>
|
||||
|
@ -48,7 +48,7 @@ public partial class Workspaces : ComponentBase
|
||||
}
|
||||
};
|
||||
|
||||
private readonly HashSet<ITreeItem> treeItems = new();
|
||||
private readonly List<TreeItemData<ITreeItem>> treeItems = new();
|
||||
|
||||
#region Overrides of ComponentBase
|
||||
|
||||
@ -70,7 +70,10 @@ public partial class Workspaces : ComponentBase
|
||||
private async Task LoadTreeItems()
|
||||
{
|
||||
this.treeItems.Clear();
|
||||
this.treeItems.Add(new TreeItemData
|
||||
this.treeItems.Add(new TreeItemData<ITreeItem>
|
||||
{
|
||||
Expandable = true,
|
||||
Value = new TreeItemData
|
||||
{
|
||||
Depth = 0,
|
||||
Branch = WorkspaceBranch.WORKSPACES,
|
||||
@ -79,10 +82,19 @@ public partial class Workspaces : ComponentBase
|
||||
Expandable = true,
|
||||
Path = "root",
|
||||
Children = await this.LoadWorkspaces(),
|
||||
},
|
||||
});
|
||||
|
||||
this.treeItems.Add(new TreeDivider());
|
||||
this.treeItems.Add(new TreeItemData
|
||||
this.treeItems.Add(new TreeItemData<ITreeItem>
|
||||
{
|
||||
Expandable = false,
|
||||
Value = new TreeDivider(),
|
||||
});
|
||||
|
||||
this.treeItems.Add(new TreeItemData<ITreeItem>
|
||||
{
|
||||
Expandable = true,
|
||||
Value = new TreeItemData
|
||||
{
|
||||
Depth = 0,
|
||||
Branch = WorkspaceBranch.TEMPORARY_CHATS,
|
||||
@ -91,12 +103,13 @@ public partial class Workspaces : ComponentBase
|
||||
Expandable = true,
|
||||
Path = "temp",
|
||||
Children = await this.LoadTemporaryChats(),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
private async Task<HashSet<ITreeItem>> LoadTemporaryChats()
|
||||
private async Task<IReadOnlyCollection<TreeItemData<ITreeItem>>> LoadTemporaryChats()
|
||||
{
|
||||
var tempChildren = new HashSet<ITreeItem>();
|
||||
var tempChildren = new List<TreeItemData<ITreeItem>>();
|
||||
|
||||
//
|
||||
// Search for workspace folders in the data directory:
|
||||
@ -115,7 +128,10 @@ public partial class Workspaces : ComponentBase
|
||||
var chatNamePath = Path.Join(tempChatDirPath, "name");
|
||||
var chatName = await File.ReadAllTextAsync(chatNamePath, Encoding.UTF8);
|
||||
|
||||
tempChildren.Add(new TreeItemData
|
||||
tempChildren.Add(new TreeItemData<ITreeItem>
|
||||
{
|
||||
Expandable = false,
|
||||
Value = new TreeItemData
|
||||
{
|
||||
Type = TreeItemType.CHAT,
|
||||
Depth = 1,
|
||||
@ -124,6 +140,7 @@ public partial class Workspaces : ComponentBase
|
||||
Icon = Icons.Material.Filled.Timer,
|
||||
Expandable = false,
|
||||
Path = tempChatDirPath,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@ -140,9 +157,9 @@ public partial class Workspaces : ComponentBase
|
||||
return await File.ReadAllTextAsync(workspaceNamePath, Encoding.UTF8);
|
||||
}
|
||||
|
||||
private async Task<HashSet<ITreeItem>> LoadWorkspaces()
|
||||
private async Task<IReadOnlyCollection<TreeItemData<ITreeItem>>> LoadWorkspaces()
|
||||
{
|
||||
var workspaces = new HashSet<ITreeItem>();
|
||||
var workspaces = new List<TreeItemData<ITreeItem>>();
|
||||
|
||||
//
|
||||
// Search for workspace folders in the data directory:
|
||||
@ -161,7 +178,10 @@ public partial class Workspaces : ComponentBase
|
||||
var workspaceNamePath = Path.Join(workspaceDirPath, "name");
|
||||
var workspaceName = await File.ReadAllTextAsync(workspaceNamePath, Encoding.UTF8);
|
||||
|
||||
workspaces.Add(new TreeItemData
|
||||
workspaces.Add(new TreeItemData<ITreeItem>
|
||||
{
|
||||
Expandable = true,
|
||||
Value = new TreeItemData
|
||||
{
|
||||
Type = TreeItemType.WORKSPACE,
|
||||
Depth = 1,
|
||||
@ -171,16 +191,21 @@ public partial class Workspaces : ComponentBase
|
||||
Expandable = true,
|
||||
Path = workspaceDirPath,
|
||||
Children = await this.LoadWorkspaceChats(workspaceDirPath),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
workspaces.Add(new TreeButton(WorkspaceBranch.WORKSPACES, 1, "Add workspace",Icons.Material.Filled.LibraryAdd, this.AddWorkspace));
|
||||
workspaces.Add(new TreeItemData<ITreeItem>
|
||||
{
|
||||
Expandable = false,
|
||||
Value = new TreeButton(WorkspaceBranch.WORKSPACES, 1, "Add workspace",Icons.Material.Filled.LibraryAdd, this.AddWorkspace),
|
||||
});
|
||||
return workspaces;
|
||||
}
|
||||
|
||||
private async Task<HashSet<ITreeItem>> LoadWorkspaceChats(string workspacePath)
|
||||
private async Task<IReadOnlyCollection<TreeItemData<ITreeItem>>> LoadWorkspaceChats(string workspacePath)
|
||||
{
|
||||
var workspaceChats = new HashSet<ITreeItem>();
|
||||
var workspaceChats = new List<TreeItemData<ITreeItem>>();
|
||||
|
||||
// Enumerate the workspace directory:
|
||||
foreach (var chatPath in Directory.EnumerateDirectories(workspacePath))
|
||||
@ -189,7 +214,10 @@ public partial class Workspaces : ComponentBase
|
||||
var chatNamePath = Path.Join(chatPath, "name");
|
||||
var chatName = await File.ReadAllTextAsync(chatNamePath, Encoding.UTF8);
|
||||
|
||||
workspaceChats.Add(new TreeItemData
|
||||
workspaceChats.Add(new TreeItemData<ITreeItem>
|
||||
{
|
||||
Expandable = false,
|
||||
Value = new TreeItemData
|
||||
{
|
||||
Type = TreeItemType.CHAT,
|
||||
Depth = 2,
|
||||
@ -198,10 +226,16 @@ public partial class Workspaces : ComponentBase
|
||||
Icon = Icons.Material.Filled.Chat,
|
||||
Expandable = false,
|
||||
Path = chatPath,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
workspaceChats.Add(new TreeButton(WorkspaceBranch.WORKSPACES, 2, "Add chat",Icons.Material.Filled.AddComment, () => this.AddChat(workspacePath)));
|
||||
workspaceChats.Add(new TreeItemData<ITreeItem>
|
||||
{
|
||||
Expandable = false,
|
||||
Value = new TreeButton(WorkspaceBranch.WORKSPACES, 2, "Add chat",Icons.Material.Filled.AddComment, () => this.AddChat(workspacePath)),
|
||||
});
|
||||
|
||||
return workspaceChats;
|
||||
}
|
||||
|
||||
@ -247,7 +281,7 @@ public partial class Workspaces : ComponentBase
|
||||
|
||||
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>("Load Chat", dialogParameters, DialogOptions.FULLSCREEN);
|
||||
var dialogResult = await dialogReference.Result;
|
||||
if (dialogResult.Canceled)
|
||||
if (dialogResult is null || dialogResult.Canceled)
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -294,7 +328,7 @@ public partial class Workspaces : ComponentBase
|
||||
|
||||
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>("Delete Chat", dialogParameters, DialogOptions.FULLSCREEN);
|
||||
var dialogResult = await dialogReference.Result;
|
||||
if (dialogResult.Canceled)
|
||||
if (dialogResult is null || dialogResult.Canceled)
|
||||
return;
|
||||
}
|
||||
|
||||
@ -331,7 +365,7 @@ public partial class Workspaces : ComponentBase
|
||||
|
||||
var dialogReference = await this.DialogService.ShowAsync<SingleInputDialog>("Rename Chat", dialogParameters, DialogOptions.FULLSCREEN);
|
||||
var dialogResult = await dialogReference.Result;
|
||||
if (dialogResult.Canceled)
|
||||
if (dialogResult is null || dialogResult.Canceled)
|
||||
return;
|
||||
|
||||
chat.Name = (dialogResult.Data as string)!;
|
||||
@ -356,7 +390,7 @@ public partial class Workspaces : ComponentBase
|
||||
|
||||
var dialogReference = await this.DialogService.ShowAsync<SingleInputDialog>("Rename Workspace", dialogParameters, DialogOptions.FULLSCREEN);
|
||||
var dialogResult = await dialogReference.Result;
|
||||
if (dialogResult.Canceled)
|
||||
if (dialogResult is null || dialogResult.Canceled)
|
||||
return;
|
||||
|
||||
var alteredWorkspaceName = (dialogResult.Data as string)!;
|
||||
@ -377,7 +411,7 @@ public partial class Workspaces : ComponentBase
|
||||
|
||||
var dialogReference = await this.DialogService.ShowAsync<SingleInputDialog>("Add Workspace", dialogParameters, DialogOptions.FULLSCREEN);
|
||||
var dialogResult = await dialogReference.Result;
|
||||
if (dialogResult.Canceled)
|
||||
if (dialogResult is null || dialogResult.Canceled)
|
||||
return;
|
||||
|
||||
var workspaceId = Guid.NewGuid();
|
||||
@ -408,7 +442,7 @@ public partial class Workspaces : ComponentBase
|
||||
|
||||
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>("Delete Workspace", dialogParameters, DialogOptions.FULLSCREEN);
|
||||
var dialogResult = await dialogReference.Result;
|
||||
if (dialogResult.Canceled)
|
||||
if (dialogResult is null || dialogResult.Canceled)
|
||||
return;
|
||||
|
||||
Directory.Delete(workspacePath, true);
|
||||
@ -430,7 +464,7 @@ public partial class Workspaces : ComponentBase
|
||||
|
||||
var dialogReference = await this.DialogService.ShowAsync<WorkspaceSelectionDialog>("Move Chat to Workspace", dialogParameters, DialogOptions.FULLSCREEN);
|
||||
var dialogResult = await dialogReference.Result;
|
||||
if (dialogResult.Canceled)
|
||||
if (dialogResult is null || dialogResult.Canceled)
|
||||
return;
|
||||
|
||||
var workspaceId = dialogResult.Data is Guid id ? id : default;
|
||||
@ -475,7 +509,7 @@ public partial class Workspaces : ComponentBase
|
||||
|
||||
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>("Create Chat", dialogParameters, DialogOptions.FULLSCREEN);
|
||||
var dialogResult = await dialogReference.Result;
|
||||
if (dialogResult.Canceled)
|
||||
if (dialogResult is null || dialogResult.Canceled)
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
using AIStudio.Settings;
|
||||
using AIStudio.Tools;
|
||||
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
@ -23,7 +24,12 @@ public partial class ConfigurationBase : ComponentBase
|
||||
public string OptionHelp { get; set; } = string.Empty;
|
||||
|
||||
[Inject]
|
||||
public SettingsManager SettingsManager { get; init; } = null!;
|
||||
protected SettingsManager SettingsManager { get; init; } = null!;
|
||||
|
||||
[Inject]
|
||||
protected MessageBus MessageBus { get; init; } = null!;
|
||||
|
||||
protected const string MARGIN_CLASS = "mb-6";
|
||||
|
||||
protected async Task InformAboutChange() => await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
|
||||
}
|
@ -35,5 +35,6 @@ public partial class ConfigurationOption : ConfigurationBase
|
||||
{
|
||||
this.StateUpdate(updatedState);
|
||||
await this.SettingsManager.StoreSettings();
|
||||
await this.InformAboutChange();
|
||||
}
|
||||
}
|
@ -30,6 +30,7 @@ public partial class ConfigurationSelect<T> : ConfigurationBase
|
||||
{
|
||||
this.SelectionUpdate(updatedValue);
|
||||
await this.SettingsManager.StoreSettings();
|
||||
await this.InformAboutChange();
|
||||
}
|
||||
|
||||
private static string GetClass => $"{MARGIN_CLASS} rounded-lg";
|
||||
|
@ -47,4 +47,12 @@ public static class ConfigurationSelectDataFactory
|
||||
yield return new("Delete temporary chats older than 180 days", WorkspaceStorageTemporaryMaintenancePolicy.DELETE_OLDER_THAN_180_DAYS);
|
||||
yield return new("Delete temporary chats older than 1 year", WorkspaceStorageTemporaryMaintenancePolicy.DELETE_OLDER_THAN_365_DAYS);
|
||||
}
|
||||
|
||||
public static IEnumerable<ConfigurationSelectData<NavBehavior>> GetNavBehaviorData()
|
||||
{
|
||||
yield return new("Navigation expands on mouse hover", NavBehavior.EXPAND_ON_HOVER);
|
||||
yield return new("Navigation never expands, but there are tooltips", NavBehavior.NEVER_EXPAND_USE_TOOLTIPS);
|
||||
yield return new("Navigation never expands, no tooltips", NavBehavior.NEVER_EXPAND_NO_TOOLTIPS);
|
||||
yield return new("Always expand navigation", NavBehavior.ALWAYS_EXPAND);
|
||||
}
|
||||
}
|
@ -1,36 +1,32 @@
|
||||
@inherits LayoutComponentBase
|
||||
@using AIStudio.Settings
|
||||
@inherits LayoutComponentBase
|
||||
|
||||
<MudPaper Height="calc(100vh);" Elevation="0">
|
||||
<MudLayout>
|
||||
@if (!this.performingUpdate)
|
||||
{
|
||||
<MudDrawerContainer Class="mud-height-full absolute">
|
||||
<MudDrawer Elevation="0" Variant="@DrawerVariant.Mini" OpenMiniOnHover="@true" Color="Color.Default">
|
||||
<MudDrawer @bind-Open="@this.navBarOpen" MiniWidth="@NAVBAR_COLLAPSED_WIDTH" Width="@NAVBAR_EXPANDED_WIDTH" Elevation="1" Fixed="@true" Variant="@DrawerVariant.Mini" OpenMiniOnHover="@(this.SettingsManager.ConfigurationData.NavigationBehavior is NavBehavior.EXPAND_ON_HOVER)" Color="Color.Default">
|
||||
<MudNavMenu>
|
||||
<MudTooltip Text="Home" Placement="Placement.Right">
|
||||
<MudNavLink Href="/" Match="NavLinkMatch.All" Icon="@Icons.Material.Filled.Home">Home</MudNavLink>
|
||||
</MudTooltip>
|
||||
<MudTooltip Text="Chat" Placement="Placement.Right">
|
||||
<MudNavLink Href="/chat" Icon="@Icons.Material.Filled.Chat">Chat</MudNavLink>
|
||||
</MudTooltip>
|
||||
<MudTooltip Text="Assistants" Placement="Placement.Right">
|
||||
<MudNavLink Href="/assistants" Icon="@Icons.Material.Filled.Apps">Assistants</MudNavLink>
|
||||
</MudTooltip>
|
||||
<MudTooltip Text="Supporters" Placement="Placement.Right">
|
||||
<MudNavLink Href="/supporters" Icon="@Icons.Material.Filled.Favorite" IconColor="Color.Error">Supporters</MudNavLink>
|
||||
</MudTooltip>
|
||||
<MudTooltip Text="About" Placement="Placement.Right">
|
||||
<MudNavLink Href="/about" Icon="@Icons.Material.Filled.Info">About</MudNavLink>
|
||||
</MudTooltip>
|
||||
<MudTooltip Text="Settings" Placement="Placement.Right">
|
||||
<MudNavLink Href="/settings" Icon="@Icons.Material.Filled.Settings">Settings</MudNavLink>
|
||||
@foreach (var navBarItem in NAV_ITEMS)
|
||||
{
|
||||
if (this.SettingsManager.ConfigurationData.NavigationBehavior is NavBehavior.NEVER_EXPAND_USE_TOOLTIPS)
|
||||
{
|
||||
<MudTooltip Text="@navBarItem.Name" Placement="Placement.Right">
|
||||
<MudNavLink Href="@navBarItem.Path" Match="@(navBarItem.MatchAll ? NavLinkMatch.All : NavLinkMatch.Prefix)" Icon="@navBarItem.Icon" IconColor="@navBarItem.IconColor">@navBarItem.Name</MudNavLink>
|
||||
</MudTooltip>
|
||||
}
|
||||
else
|
||||
{
|
||||
<MudNavLink Href="@navBarItem.Path" Match="@(navBarItem.MatchAll ? NavLinkMatch.All : NavLinkMatch.Prefix)" Icon="@navBarItem.Icon" IconColor="@navBarItem.IconColor">@navBarItem.Name</MudNavLink>
|
||||
}
|
||||
}
|
||||
</MudNavMenu>
|
||||
</MudDrawer>
|
||||
</MudDrawerContainer>
|
||||
}
|
||||
|
||||
<MudMainContent Class="mud-height-full pt-1">
|
||||
<MudMainContent Class="mud-height-full pt-1" Style="@this.PaddingLeft">
|
||||
<MudContainer Fixed="@true" Class="mud-height-full" Style="margin-left: 5em; width: calc(100% - 5em);">
|
||||
@if (!this.performingUpdate && this.IsUpdateAlertVisible)
|
||||
{
|
||||
|
@ -34,12 +34,30 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver
|
||||
|
||||
public string AdditionalHeight { get; private set; } = "0em";
|
||||
|
||||
private string PaddingLeft => this.navBarOpen ? $"padding-left: {NAVBAR_EXPANDED_WIDTH_INT - NAVBAR_COLLAPSED_WIDTH_INT}em;" : "padding-left: 0em;";
|
||||
|
||||
private const int NAVBAR_COLLAPSED_WIDTH_INT = 4;
|
||||
private const int NAVBAR_EXPANDED_WIDTH_INT = 10;
|
||||
private static readonly string NAVBAR_COLLAPSED_WIDTH = $"{NAVBAR_COLLAPSED_WIDTH_INT}em";
|
||||
private static readonly string NAVBAR_EXPANDED_WIDTH = $"{NAVBAR_EXPANDED_WIDTH_INT}em";
|
||||
|
||||
private bool navBarOpen;
|
||||
private bool isUpdateAvailable;
|
||||
private bool performingUpdate;
|
||||
private bool userDismissedUpdate;
|
||||
private string updateToVersion = string.Empty;
|
||||
private UpdateResponse? currentUpdateResponse;
|
||||
|
||||
private static readonly IReadOnlyCollection<NavBarItem> NAV_ITEMS = new List<NavBarItem>
|
||||
{
|
||||
new("Home", Icons.Material.Filled.Home, Color.Default, "/", true),
|
||||
new("Chat", Icons.Material.Filled.Chat, Color.Default, "/chat", false),
|
||||
new("Assistants", Icons.Material.Filled.Apps, Color.Default ,"/assistants", false),
|
||||
new("Supporters", Icons.Material.Filled.Favorite, Color.Error ,"/supporters", false),
|
||||
new("About", Icons.Material.Filled.Info, Color.Default ,"/about", false),
|
||||
new("Settings", Icons.Material.Filled.Settings, Color.Default ,"/settings", false),
|
||||
};
|
||||
|
||||
#region Overrides of ComponentBase
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
@ -63,12 +81,16 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver
|
||||
|
||||
// Register this component with the message bus:
|
||||
this.MessageBus.RegisterComponent(this);
|
||||
this.MessageBus.ApplyFilters(this, [], [ Event.UPDATE_AVAILABLE, Event.USER_SEARCH_FOR_UPDATE ]);
|
||||
this.MessageBus.ApplyFilters(this, [], [ Event.UPDATE_AVAILABLE, Event.USER_SEARCH_FOR_UPDATE, Event.CONFIGURATION_CHANGED ]);
|
||||
|
||||
// Set the js runtime for the update service:
|
||||
UpdateService.SetBlazorDependencies(this.JsRuntime, this.Snackbar);
|
||||
TemporaryChatService.Initialize();
|
||||
|
||||
// Should the navigation bar be open by default?
|
||||
if(this.SettingsManager.ConfigurationData.NavigationBehavior is NavBehavior.ALWAYS_EXPAND)
|
||||
this.navBarOpen = true;
|
||||
|
||||
await base.OnInitializedAsync();
|
||||
}
|
||||
|
||||
@ -96,6 +118,15 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Event.CONFIGURATION_CHANGED:
|
||||
if(this.SettingsManager.ConfigurationData.NavigationBehavior is NavBehavior.ALWAYS_EXPAND)
|
||||
this.navBarOpen = true;
|
||||
else
|
||||
this.navBarOpen = false;
|
||||
|
||||
this.StateHasChanged();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -151,7 +182,7 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver
|
||||
|
||||
var dialogReference = await this.DialogService.ShowAsync<UpdateDialog>("Update", dialogParameters, DialogOptions.FULLSCREEN_NO_HEADER);
|
||||
var dialogResult = await dialogReference.Result;
|
||||
if (dialogResult.Canceled)
|
||||
if (dialogResult is null || dialogResult.Canceled)
|
||||
return;
|
||||
|
||||
this.performingUpdate = true;
|
||||
@ -170,7 +201,7 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver
|
||||
|
||||
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>("Leave Chat Page", dialogParameters, DialogOptions.FULLSCREEN);
|
||||
var dialogResult = await dialogReference.Result;
|
||||
if (dialogResult.Canceled)
|
||||
if (dialogResult is null || dialogResult.Canceled)
|
||||
{
|
||||
context.PreventNavigation();
|
||||
return;
|
||||
|
3
app/MindWork AI Studio/Components/Layout/NavBarItem.cs
Normal file
3
app/MindWork AI Studio/Components/Layout/NavBarItem.cs
Normal file
@ -0,0 +1,3 @@
|
||||
namespace AIStudio.Components.Layout;
|
||||
|
||||
public record NavBarItem(string Name, string Icon, Color IconColor, string Path, bool MatchAll);
|
@ -9,14 +9,14 @@
|
||||
<MudText>
|
||||
The following list shows the versions of the MindWork AI Studio, the used compilers, build time, etc.:
|
||||
</MudText>
|
||||
<MudList Clickable="@true">
|
||||
<MudListItem Icon="@Icons.Material.Outlined.Chat" Text="@VersionApp"/>
|
||||
<MudListItem Icon="@Icons.Material.Outlined.Timer" Text="@BuildTime"/>
|
||||
<MudListItem Icon="@Icons.Material.Outlined.Build" Text="@VersionDotnetSdk"/>
|
||||
<MudListItem Icon="@Icons.Material.Outlined.Memory" Text="@VersionDotnetRuntime"/>
|
||||
<MudListItem Icon="@Icons.Material.Outlined.Build" Text="@VersionRust"/>
|
||||
<MudListItem Icon="@Icons.Material.Outlined.Widgets" Text="@MudBlazorVersion"/>
|
||||
<MudListItem Icon="@Icons.Material.Outlined.Memory" Text="@TauriVersion"/>
|
||||
<MudList T="string">
|
||||
<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.Build" Text="@VersionDotnetSdk"/>
|
||||
<MudListItem T="string" Icon="@Icons.Material.Outlined.Memory" Text="@VersionDotnetRuntime"/>
|
||||
<MudListItem T="string" Icon="@Icons.Material.Outlined.Build" Text="@VersionRust"/>
|
||||
<MudListItem T="string" Icon="@Icons.Material.Outlined.Widgets" Text="@MudBlazorVersion"/>
|
||||
<MudListItem T="string" Icon="@Icons.Material.Outlined.Memory" Text="@TauriVersion"/>
|
||||
</MudList>
|
||||
<MudButton Variant="Variant.Filled" Color="Color.Info" StartIcon="@Icons.Material.Filled.Update" OnClick="() => this.CheckForUpdate()">
|
||||
Check for updates
|
||||
|
@ -235,7 +235,7 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable
|
||||
|
||||
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>("Delete Chat", dialogParameters, DialogOptions.FULLSCREEN);
|
||||
var dialogResult = await dialogReference.Result;
|
||||
if (dialogResult.Canceled)
|
||||
if (dialogResult is null || dialogResult.Canceled)
|
||||
return;
|
||||
}
|
||||
|
||||
@ -297,7 +297,7 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable
|
||||
|
||||
var confirmationDialogReference = await this.DialogService.ShowAsync<ConfirmDialog>("Unsaved Changes", confirmationDialogParameters, DialogOptions.FULLSCREEN);
|
||||
var confirmationDialogResult = await confirmationDialogReference.Result;
|
||||
if (confirmationDialogResult.Canceled)
|
||||
if (confirmationDialogResult is null || confirmationDialogResult.Canceled)
|
||||
return;
|
||||
}
|
||||
|
||||
@ -310,7 +310,7 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable
|
||||
|
||||
var dialogReference = await this.DialogService.ShowAsync<WorkspaceSelectionDialog>("Move Chat to Workspace", dialogParameters, DialogOptions.FULLSCREEN);
|
||||
var dialogResult = await dialogReference.Result;
|
||||
if (dialogResult.Canceled)
|
||||
if (dialogResult is null || dialogResult.Canceled)
|
||||
return;
|
||||
|
||||
var workspaceId = dialogResult.Data is Guid id ? id : default;
|
||||
|
@ -1,5 +1,3 @@
|
||||
using AIStudio.Provider;
|
||||
|
||||
namespace AIStudio.Components.Pages.IconFinder;
|
||||
|
||||
public partial class AssistantIconFinder : AssistantBaseCore
|
||||
|
@ -73,5 +73,6 @@
|
||||
<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="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="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."/>
|
||||
</MudPaper>
|
||||
</InnerScrolling>
|
@ -1,6 +1,8 @@
|
||||
using AIStudio.Components.CommonDialogs;
|
||||
using AIStudio.Provider;
|
||||
using AIStudio.Settings;
|
||||
using AIStudio.Tools;
|
||||
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
using DialogOptions = AIStudio.Components.CommonDialogs.DialogOptions;
|
||||
@ -20,6 +22,9 @@ public partial class Settings : ComponentBase
|
||||
[Inject]
|
||||
public IJSRuntime JsRuntime { get; init; } = null!;
|
||||
|
||||
[Inject]
|
||||
protected MessageBus MessageBus { get; init; } = null!;
|
||||
|
||||
#region Provider related
|
||||
|
||||
private async Task AddProvider()
|
||||
@ -31,14 +36,15 @@ public partial class Settings : ComponentBase
|
||||
|
||||
var dialogReference = await this.DialogService.ShowAsync<ProviderDialog>("Add Provider", dialogParameters, DialogOptions.FULLSCREEN);
|
||||
var dialogResult = await dialogReference.Result;
|
||||
if (dialogResult.Canceled)
|
||||
if (dialogResult is null || dialogResult.Canceled)
|
||||
return;
|
||||
|
||||
var addedProvider = (AIStudio.Settings.Provider)dialogResult.Data;
|
||||
var addedProvider = (AIStudio.Settings.Provider)dialogResult.Data!;
|
||||
addedProvider = addedProvider with { Num = this.SettingsManager.ConfigurationData.NextProviderNum++ };
|
||||
|
||||
this.SettingsManager.ConfigurationData.Providers.Add(addedProvider);
|
||||
await this.SettingsManager.StoreSettings();
|
||||
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
|
||||
}
|
||||
|
||||
private async Task EditProvider(AIStudio.Settings.Provider provider)
|
||||
@ -58,10 +64,10 @@ public partial class Settings : ComponentBase
|
||||
|
||||
var dialogReference = await this.DialogService.ShowAsync<ProviderDialog>("Edit Provider", dialogParameters, DialogOptions.FULLSCREEN);
|
||||
var dialogResult = await dialogReference.Result;
|
||||
if (dialogResult.Canceled)
|
||||
if (dialogResult is null || dialogResult.Canceled)
|
||||
return;
|
||||
|
||||
var editedProvider = (AIStudio.Settings.Provider)dialogResult.Data;
|
||||
var editedProvider = (AIStudio.Settings.Provider)dialogResult.Data!;
|
||||
|
||||
// Set the provider number if it's not set. This is important for providers
|
||||
// added before we started saving the provider number.
|
||||
@ -70,6 +76,7 @@ public partial class Settings : ComponentBase
|
||||
|
||||
this.SettingsManager.ConfigurationData.Providers[this.SettingsManager.ConfigurationData.Providers.IndexOf(provider)] = editedProvider;
|
||||
await this.SettingsManager.StoreSettings();
|
||||
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
|
||||
}
|
||||
|
||||
private async Task DeleteProvider(AIStudio.Settings.Provider provider)
|
||||
@ -81,7 +88,7 @@ public partial class Settings : ComponentBase
|
||||
|
||||
var dialogReference = await this.DialogService.ShowAsync<ConfirmDialog>("Delete Provider", dialogParameters, DialogOptions.FULLSCREEN);
|
||||
var dialogResult = await dialogReference.Result;
|
||||
if (dialogResult.Canceled)
|
||||
if (dialogResult is null || dialogResult.Canceled)
|
||||
return;
|
||||
|
||||
var providerInstance = provider.CreateProvider();
|
||||
@ -91,6 +98,8 @@ public partial class Settings : ComponentBase
|
||||
this.SettingsManager.ConfigurationData.Providers.Remove(provider);
|
||||
await this.SettingsManager.StoreSettings();
|
||||
}
|
||||
|
||||
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
|
||||
}
|
||||
|
||||
private string GetProviderDashboardURL(Providers provider) => provider switch
|
||||
|
@ -1,4 +1,3 @@
|
||||
using AIStudio.Provider;
|
||||
using AIStudio.Tools;
|
||||
|
||||
namespace AIStudio.Components.Pages.TextSummarizer;
|
||||
|
@ -1,4 +1,3 @@
|
||||
using AIStudio.Provider;
|
||||
using AIStudio.Tools;
|
||||
|
||||
namespace AIStudio.Components.Pages.Translator;
|
||||
|
@ -7,4 +7,5 @@
|
||||
|
||||
<MudThemeProvider />
|
||||
<MudDialogProvider />
|
||||
<MudPopoverProvider />
|
||||
<MudSnackbarProvider />
|
@ -45,8 +45,8 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="8.0.6" />
|
||||
<PackageReference Include="MudBlazor" Version="6.20.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="8.0.7" />
|
||||
<PackageReference Include="MudBlazor" Version="7.4.0" />
|
||||
<PackageReference Include="MudBlazor.Markdown" Version="1.0.2" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@ -51,4 +51,9 @@ public sealed class Data
|
||||
/// 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;
|
||||
}
|
9
app/MindWork AI Studio/Settings/NavBehavior.cs
Normal file
9
app/MindWork AI Studio/Settings/NavBehavior.cs
Normal file
@ -0,0 +1,9 @@
|
||||
namespace AIStudio.Settings;
|
||||
|
||||
public enum NavBehavior
|
||||
{
|
||||
EXPAND_ON_HOVER,
|
||||
NEVER_EXPAND_USE_TOOLTIPS,
|
||||
NEVER_EXPAND_NO_TOOLTIPS,
|
||||
ALWAYS_EXPAND,
|
||||
}
|
@ -79,10 +79,10 @@
|
||||
{
|
||||
<MudPaper Class="pa-2 mt-3">
|
||||
<MudText Typo="Typo.h6">Issues</MudText>
|
||||
<MudList Clickable="@true">
|
||||
<MudList T="string">
|
||||
@foreach (var issue in this.dataIssues)
|
||||
{
|
||||
<MudListItem Icon="@Icons.Material.Filled.Error" IconColor="Color.Error">
|
||||
<MudListItem T="string" Icon="@Icons.Material.Filled.Error" IconColor="Color.Error">
|
||||
@issue
|
||||
</MudListItem>
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ public enum Event
|
||||
|
||||
// Common events:
|
||||
STATE_HAS_CHANGED,
|
||||
CONFIGURATION_CHANGED,
|
||||
|
||||
// Update events:
|
||||
USER_SEARCH_FOR_UPDATE,
|
||||
|
@ -4,9 +4,9 @@
|
||||
"net8.0": {
|
||||
"Microsoft.Extensions.FileProviders.Embedded": {
|
||||
"type": "Direct",
|
||||
"requested": "[8.0.6, )",
|
||||
"resolved": "8.0.6",
|
||||
"contentHash": "hQlf5+YxiUbKdpaPBf/zdMGItnWF8ai9ToPjeZ6gnxT10V4RGDKvChl5MSdc838+2SRHLAC0cdJwG0+L7dqR0g==",
|
||||
"requested": "[8.0.7, )",
|
||||
"resolved": "8.0.7",
|
||||
"contentHash": "ABsn0T09b5lzVNbOcuRc10+kNZkO+RGtZWfzqVay0Ah+/ouhEvG7JrXc+9+7zFgoPuH4E4N6+uWfTp+pJqMeGw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.FileProviders.Abstractions": "8.0.0"
|
||||
}
|
||||
@ -19,13 +19,13 @@
|
||||
},
|
||||
"MudBlazor": {
|
||||
"type": "Direct",
|
||||
"requested": "[6.20.0, )",
|
||||
"resolved": "6.20.0",
|
||||
"contentHash": "2MqW/E1OLszSqDhW06rpRTN4OpIRJU0iVzeiZLPzymckrKJH1Hg09St+O3kaEnsbXRcjcdM9iE5cSKzCgxvySQ==",
|
||||
"requested": "[7.4.0, )",
|
||||
"resolved": "7.4.0",
|
||||
"contentHash": "dm8ZD6OhyI6icE3Si0V3BJvwPZp8fEspPFq4/iQXU8/i7L39/ny2bPgQqPnQmIojppd9cR/H4RdsaBlSLe6rIw==",
|
||||
"dependencies": {
|
||||
"Microsoft.AspNetCore.Components": "8.0.3",
|
||||
"Microsoft.AspNetCore.Components.Web": "8.0.3",
|
||||
"Microsoft.Extensions.Localization": "8.0.3"
|
||||
"Microsoft.AspNetCore.Components": "8.0.6",
|
||||
"Microsoft.AspNetCore.Components.Web": "8.0.6",
|
||||
"Microsoft.Extensions.Localization": "8.0.6"
|
||||
}
|
||||
},
|
||||
"MudBlazor.Markdown": {
|
||||
@ -45,53 +45,53 @@
|
||||
},
|
||||
"Microsoft.AspNetCore.Authorization": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.3",
|
||||
"contentHash": "9Nic17acgZbysUlhGc+TEd9F8jI01kC6+V31sC7/xI5v2OSWGL8NhdYaB/Iu4KnDRoQEolg6qvepGsVfeYpIYA==",
|
||||
"resolved": "8.0.6",
|
||||
"contentHash": "H1CSbD7UeSPsrJSUpvbms6SqWMa5y8ch4Rw+gyHh2uztOEb20fTP2r0AUnStn1Q9WYghikiDO5wzkgV+n6KC2Q==",
|
||||
"dependencies": {
|
||||
"Microsoft.AspNetCore.Metadata": "8.0.3",
|
||||
"Microsoft.AspNetCore.Metadata": "8.0.6",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "8.0.1",
|
||||
"Microsoft.Extensions.Options": "8.0.2"
|
||||
}
|
||||
},
|
||||
"Microsoft.AspNetCore.Components": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.3",
|
||||
"contentHash": "q1Da8sfxG+B+BSYpc/3RKNEdzGcLbDTXkTUqekY65kXMMVCTqTAQ0Zs4csmB7FNVTFSjwaw1dGMFD0bQ+erlBw==",
|
||||
"resolved": "8.0.6",
|
||||
"contentHash": "Je2l+rd5i8gB+ZWsN5wBHOsnyAh81h6+a5vNq6rjfQhM2ZYxH+BVsmanCYa+F8BFy6rmd+ZL61SEiNaAyAOgtg==",
|
||||
"dependencies": {
|
||||
"Microsoft.AspNetCore.Authorization": "8.0.3",
|
||||
"Microsoft.AspNetCore.Components.Analyzers": "8.0.3"
|
||||
"Microsoft.AspNetCore.Authorization": "8.0.6",
|
||||
"Microsoft.AspNetCore.Components.Analyzers": "8.0.6"
|
||||
}
|
||||
},
|
||||
"Microsoft.AspNetCore.Components.Analyzers": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.3",
|
||||
"contentHash": "iERLuYM+YFI/K1jkinr1YeAkJYHUcijPiPCKgmgs2ZhJLqiIVJRT08vUtIsfhiFtGiI5MIzK0R1BZHyS3yAQng=="
|
||||
"resolved": "8.0.6",
|
||||
"contentHash": "SEL0CN1jJdJkCDwRox3kSY1ffMnahlOCDJZYrYWfQ6ftjqRuuiPtwyvI3VIeVHLcpT3VP1AXww8wzKDK3oeFxg=="
|
||||
},
|
||||
"Microsoft.AspNetCore.Components.Forms": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.3",
|
||||
"contentHash": "OxY5NDmePnn6FMb+Fum57YL7LCHk3u2Wg0qSln3uZSayo+oIxYuoGnqH2dUMp1P5vOPfq17NKCIIEbxfU2dirQ==",
|
||||
"resolved": "8.0.6",
|
||||
"contentHash": "49wIE1ns3ZGDU4NPMcKCSTC716IxujUeaynsUyflM5Qmb2WlF6M6m4pMcJ6UET1Ixmn027nZjMEc8J7pU4BLBg==",
|
||||
"dependencies": {
|
||||
"Microsoft.AspNetCore.Components": "8.0.3"
|
||||
"Microsoft.AspNetCore.Components": "8.0.6"
|
||||
}
|
||||
},
|
||||
"Microsoft.AspNetCore.Components.Web": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.3",
|
||||
"contentHash": "bHWJiz/JhjptK3iYzha0Rm73chjFcbMAOD9DdDq2tn1rp4rQa/K7O/zdnZpSYAT3nI33Q0aY6ts6t0PUVu5hCA==",
|
||||
"resolved": "8.0.6",
|
||||
"contentHash": "xxYlTpcTEWsxaWUscDLN32mM32ysslLFtNQBS6wJOxaKJ9LCvusXDyBVEKL2DPbB8PZdereNvyrVr0deHkuOEw==",
|
||||
"dependencies": {
|
||||
"Microsoft.AspNetCore.Components": "8.0.3",
|
||||
"Microsoft.AspNetCore.Components.Forms": "8.0.3",
|
||||
"Microsoft.AspNetCore.Components": "8.0.6",
|
||||
"Microsoft.AspNetCore.Components.Forms": "8.0.6",
|
||||
"Microsoft.Extensions.DependencyInjection": "8.0.0",
|
||||
"Microsoft.Extensions.Primitives": "8.0.0",
|
||||
"Microsoft.JSInterop": "8.0.3",
|
||||
"Microsoft.JSInterop": "8.0.6",
|
||||
"System.IO.Pipelines": "8.0.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.AspNetCore.Metadata": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.3",
|
||||
"contentHash": "MAdmICjtSckGDutLRMydRI0pvBcGw/WoC4UC+hZ999idVW96l5iJlhyrtakgYkF5Rp0ekNVNWA+onP2gJZUkpw=="
|
||||
"resolved": "8.0.6",
|
||||
"contentHash": "3e7S/kz1MGds8zDA8SfQiutqifyVcULs5P/8Bxpes0WIkJRMGkU/l+XlMllj9KrDfCGwHW8bgjRy/zxfoILgfg=="
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
"type": "Transitive",
|
||||
@ -116,19 +116,19 @@
|
||||
},
|
||||
"Microsoft.Extensions.Localization": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.3",
|
||||
"contentHash": "EjHnIiEwNq9xl8S36hf0nj64IF3DTQ1l5PVK8Vo+QocYKDKpDPONHNJC8env0DPwod7T5oA1HYLLo2mdSTCgrQ==",
|
||||
"resolved": "8.0.6",
|
||||
"contentHash": "EXcSpQE6E80Qutej0ZShz1oRWBFocDzir/R3Gd1jAqZ5SnPpSr1Ep/tH5ha0cRXY22cWVuOb7I9rM32Ew+ju7g==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.1",
|
||||
"Microsoft.Extensions.Localization.Abstractions": "8.0.3",
|
||||
"Microsoft.Extensions.Localization.Abstractions": "8.0.6",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "8.0.1",
|
||||
"Microsoft.Extensions.Options": "8.0.2"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Localization.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.3",
|
||||
"contentHash": "k/kUPm1FQBxcs9/vsM1eF4qIOg2Sovqh/+KUGHur5Mc0Y3OFGuoz9ktBX7LA0gPz53SZhW3W3oaSaMFFcjgM6Q=="
|
||||
"resolved": "8.0.6",
|
||||
"contentHash": "oQdKQ4xlb+Qa4t1gWGj58cocLdWZynP+wLExIAxozh2SrvffEzTvTGI2IbRx4mBNgg9jbbyoPE8nNOwJ1Thddg=="
|
||||
},
|
||||
"Microsoft.Extensions.Logging.Abstractions": {
|
||||
"type": "Transitive",
|
||||
@ -154,8 +154,8 @@
|
||||
},
|
||||
"Microsoft.JSInterop": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.3",
|
||||
"contentHash": "Oi21Fa7KubCzafwXb2IOdSGg24+/ylYGwrJgAYdWmgXBj04Oj/1b8vr9hrcoFKjQ6K18ryHYh35ZO/CCIEhuzg=="
|
||||
"resolved": "8.0.6",
|
||||
"contentHash": "E1djWS3d41fcd++7sGlbYhOHde5Pb0oBpOcNvUbn+1ga/yCvsjzUfbd/tDRg1qacNKS0iwKWYOIqTZxJnh99dQ=="
|
||||
},
|
||||
"System.IO.Pipelines": {
|
||||
"type": "Transitive",
|
||||
@ -163,6 +163,6 @@
|
||||
"contentHash": "FHNOatmUq0sqJOkTx+UF/9YK1f180cnW5FVqnQMvYUN0elp6wFzbtPSiqbo1/ru8ICp43JM1i7kKkk6GsNGHlA=="
|
||||
}
|
||||
},
|
||||
"net8.0/osx-x64": {}
|
||||
"net8.0/osx-arm64": {}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user