mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2025-04-28 08:19:47 +00:00
Basic implementation of the workspace component
This commit is contained in:
parent
b57d7d56ea
commit
12fdcc9d8f
3
app/MindWork AI Studio/Components/Blocks/ITreeItem.cs
Normal file
3
app/MindWork AI Studio/Components/Blocks/ITreeItem.cs
Normal file
@ -0,0 +1,3 @@
|
||||
namespace AIStudio.Components.Blocks;
|
||||
|
||||
public interface ITreeItem<out T>;
|
3
app/MindWork AI Studio/Components/Blocks/TreeButton.cs
Normal file
3
app/MindWork AI Studio/Components/Blocks/TreeButton.cs
Normal file
@ -0,0 +1,3 @@
|
||||
namespace AIStudio.Components.Blocks;
|
||||
|
||||
public readonly record struct TreeButton<T>(WorkspaceBranch Branch, int Depth, string Text, string Icon) : ITreeItem<T>;
|
3
app/MindWork AI Studio/Components/Blocks/TreeDivider.cs
Normal file
3
app/MindWork AI Studio/Components/Blocks/TreeDivider.cs
Normal file
@ -0,0 +1,3 @@
|
||||
namespace AIStudio.Components.Blocks;
|
||||
|
||||
public readonly record struct TreeDivider<T> : ITreeItem<T>;
|
18
app/MindWork AI Studio/Components/Blocks/TreeItemData.cs
Normal file
18
app/MindWork AI Studio/Components/Blocks/TreeItemData.cs
Normal file
@ -0,0 +1,18 @@
|
||||
namespace AIStudio.Components.Blocks;
|
||||
|
||||
public class TreeItemData<T> : ITreeItem<T>
|
||||
{
|
||||
public WorkspaceBranch Branch { get; init; } = WorkspaceBranch.NONE;
|
||||
|
||||
public int Depth { get; init; }
|
||||
|
||||
public string Text { get; init; } = string.Empty;
|
||||
|
||||
public string Icon { get; init; } = string.Empty;
|
||||
|
||||
public T? Value { get; init; }
|
||||
|
||||
public bool Expandable { get; init; } = true;
|
||||
|
||||
public HashSet<ITreeItem<T>> Children { get; } = [];
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
namespace AIStudio.Components.Blocks;
|
||||
|
||||
public enum WorkspaceBranch
|
||||
{
|
||||
NONE,
|
||||
|
||||
WORKSPACES,
|
||||
TEMPORARY_CHATS,
|
||||
}
|
@ -1 +1,41 @@
|
||||
<MudText Typo="Typo.body1">TODO</MudText>
|
||||
<MudTreeView T="ITreeItem<string>" ServerData="@this.LoadServerData" Items="@this.initialTreeItems" MultiSelection="@false" Hover="@true" ExpandOnClick="@true">
|
||||
<ItemTemplate Context="item">
|
||||
@switch (item)
|
||||
{
|
||||
case TreeDivider<string>:
|
||||
<li style="min-height: 1em;">
|
||||
<MudDivider Style="margin-top: 1em; width: 90%; border-width: 3pt;"/>
|
||||
</li>
|
||||
break;
|
||||
|
||||
case TreeItemData<string> treeItem:
|
||||
<MudTreeViewItem T="ITreeItem<string>" Icon="@treeItem.Icon" Value="@item" LoadingIconColor="@Color.Info" 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>
|
||||
|
||||
@if (treeItem.Value is not "root" and not "temp")
|
||||
{
|
||||
<div style="justify-self: end;">
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Edit" Size="Size.Medium" Color="Color.Inherit"/>
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Delete" Size="Size.Medium" Color="Color.Inherit"/>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</BodyContent>
|
||||
</MudTreeViewItem>
|
||||
break;
|
||||
|
||||
case TreeButton<string> treeButton:
|
||||
<li>
|
||||
<div class="mud-treeview-item-content" style="background-color: unset;">
|
||||
<div class="mud-treeview-item-arrow"></div>
|
||||
<MudButton StartIcon="@treeButton.Icon" Variant="Variant.Filled">
|
||||
@treeButton.Text
|
||||
</MudButton>
|
||||
</div>
|
||||
</li>
|
||||
break;
|
||||
}
|
||||
</ItemTemplate>
|
||||
</MudTreeView>
|
@ -1,7 +1,161 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using AIStudio.Chat;
|
||||
using AIStudio.Settings;
|
||||
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace AIStudio.Components.Blocks;
|
||||
|
||||
public partial class Workspaces : ComponentBase
|
||||
{
|
||||
[Inject]
|
||||
private SettingsManager SettingsManager { get; set; } = null!;
|
||||
|
||||
[Parameter]
|
||||
public ChatThread? CurrentChatThread { get; set; }
|
||||
|
||||
private readonly HashSet<ITreeItem<string>> initialTreeItems = new();
|
||||
|
||||
#region Overrides of ComponentBase
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
//
|
||||
// Notice: In order to get the server-based loading to work, we need to respect the following rules:
|
||||
// - We must have initial tree items
|
||||
// - Those initial tree items cannot have children
|
||||
// - When assigning the tree items to the MudTreeViewItem component, we must set the Value property to the value of the item
|
||||
//
|
||||
|
||||
this.initialTreeItems.Add(new TreeItemData<string>
|
||||
{
|
||||
Depth = 0,
|
||||
Branch = WorkspaceBranch.WORKSPACES,
|
||||
Text = "Workspaces",
|
||||
Icon = Icons.Material.Filled.Folder,
|
||||
Expandable = true,
|
||||
Value = "root",
|
||||
});
|
||||
|
||||
this.initialTreeItems.Add(new TreeDivider<string>());
|
||||
this.initialTreeItems.Add(new TreeItemData<string>
|
||||
{
|
||||
Depth = 0,
|
||||
Branch = WorkspaceBranch.TEMPORARY_CHATS,
|
||||
Text = "Temporary chats",
|
||||
Icon = Icons.Material.Filled.Timer,
|
||||
Expandable = true,
|
||||
Value = "temp",
|
||||
});
|
||||
|
||||
await base.OnInitializedAsync();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private Task<HashSet<ITreeItem<string>>> LoadServerData(ITreeItem<string>? parent)
|
||||
{
|
||||
switch (parent)
|
||||
{
|
||||
case TreeItemData<string> item:
|
||||
switch (item.Branch)
|
||||
{
|
||||
case WorkspaceBranch.WORKSPACES:
|
||||
var workspaceChildren = new HashSet<ITreeItem<string>>();
|
||||
|
||||
if (item.Depth == 0)
|
||||
{
|
||||
//
|
||||
// Search for workspace folders in the data directory:
|
||||
//
|
||||
|
||||
// Get the workspace root directory:
|
||||
var workspaceDirectories = Path.Join(SettingsManager.DataDirectory, "workspaces");
|
||||
|
||||
// Ensure the directory exists:
|
||||
Directory.CreateDirectory(workspaceDirectories);
|
||||
|
||||
// Enumerate the workspace directories:
|
||||
foreach (var workspaceDirPath in Directory.EnumerateDirectories(workspaceDirectories))
|
||||
{
|
||||
workspaceChildren.Add(new TreeItemData<string>
|
||||
{
|
||||
Depth = item.Depth + 1,
|
||||
Branch = WorkspaceBranch.WORKSPACES,
|
||||
Text = Path.GetFileName(workspaceDirPath),
|
||||
Icon = Icons.Material.Filled.Description,
|
||||
Expandable = true,
|
||||
Value = workspaceDirPath,
|
||||
});
|
||||
}
|
||||
|
||||
workspaceChildren.Add(new TreeButton<string>(WorkspaceBranch.WORKSPACES, item.Depth + 1, "Add workspace",Icons.Material.Filled.Add));
|
||||
}
|
||||
|
||||
else if (item.Depth == 1)
|
||||
{
|
||||
//
|
||||
// Search for workspace chats in the workspace directory:
|
||||
//
|
||||
|
||||
// Get the workspace directory:
|
||||
var workspaceDirPath = item.Value;
|
||||
|
||||
if(workspaceDirPath is null)
|
||||
return Task.FromResult(new HashSet<ITreeItem<string>>());
|
||||
|
||||
// Enumerate the workspace directory:
|
||||
foreach (var chatPath in Directory.EnumerateDirectories(workspaceDirPath))
|
||||
{
|
||||
workspaceChildren.Add(new TreeItemData<string>
|
||||
{
|
||||
Depth = item.Depth + 1,
|
||||
Branch = WorkspaceBranch.WORKSPACES,
|
||||
Text = Path.GetFileNameWithoutExtension(chatPath),
|
||||
Icon = Icons.Material.Filled.Chat,
|
||||
Expandable = false,
|
||||
Value = chatPath,
|
||||
});
|
||||
}
|
||||
|
||||
workspaceChildren.Add(new TreeButton<string>(WorkspaceBranch.WORKSPACES, item.Depth + 1, "Add chat",Icons.Material.Filled.Add));
|
||||
}
|
||||
|
||||
return Task.FromResult(workspaceChildren);
|
||||
|
||||
case WorkspaceBranch.TEMPORARY_CHATS:
|
||||
var tempChildren = new HashSet<ITreeItem<string>>();
|
||||
|
||||
//
|
||||
// Search for workspace folders in the data directory:
|
||||
//
|
||||
|
||||
// Get the workspace root directory:
|
||||
var temporaryDirectories = Path.Join(SettingsManager.DataDirectory, "tempChats");
|
||||
|
||||
// Ensure the directory exists:
|
||||
Directory.CreateDirectory(temporaryDirectories);
|
||||
|
||||
// Enumerate the workspace directories:
|
||||
foreach (var tempChatDirPath in Directory.EnumerateDirectories(temporaryDirectories))
|
||||
{
|
||||
tempChildren.Add(new TreeItemData<string>
|
||||
{
|
||||
Depth = item.Depth + 1,
|
||||
Branch = WorkspaceBranch.TEMPORARY_CHATS,
|
||||
Text = Path.GetFileName(tempChatDirPath),
|
||||
Icon = Icons.Material.Filled.Timer,
|
||||
Expandable = false,
|
||||
Value = tempChatDirPath,
|
||||
});
|
||||
}
|
||||
|
||||
return Task.FromResult(tempChildren);
|
||||
}
|
||||
|
||||
return Task.FromResult(new HashSet<ITreeItem<string>>());
|
||||
|
||||
default:
|
||||
return Task.FromResult(new HashSet<ITreeItem<string>>());
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user