mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2025-04-28 15:59:48 +00:00
Refactored tree data structure
This commit is contained in:
parent
9f954274ff
commit
32af4211db
@ -1,3 +1,3 @@
|
|||||||
namespace AIStudio.Components.Blocks;
|
namespace AIStudio.Components.Blocks;
|
||||||
|
|
||||||
public interface ITreeItem<out T>;
|
public interface ITreeItem;
|
@ -1,3 +1,3 @@
|
|||||||
namespace AIStudio.Components.Blocks;
|
namespace AIStudio.Components.Blocks;
|
||||||
|
|
||||||
public readonly record struct TreeButton<T>(WorkspaceBranch Branch, int Depth, string Text, string Icon) : ITreeItem<T>;
|
public readonly record struct TreeButton(WorkspaceBranch Branch, int Depth, string Text, string Icon) : ITreeItem;
|
@ -1,3 +1,3 @@
|
|||||||
namespace AIStudio.Components.Blocks;
|
namespace AIStudio.Components.Blocks;
|
||||||
|
|
||||||
public readonly record struct TreeDivider<T> : ITreeItem<T>;
|
public readonly record struct TreeDivider : ITreeItem;
|
@ -1,6 +1,6 @@
|
|||||||
namespace AIStudio.Components.Blocks;
|
namespace AIStudio.Components.Blocks;
|
||||||
|
|
||||||
public class TreeItemData<T> : ITreeItem<T>
|
public class TreeItemData : ITreeItem
|
||||||
{
|
{
|
||||||
public WorkspaceBranch Branch { get; init; } = WorkspaceBranch.NONE;
|
public WorkspaceBranch Branch { get; init; } = WorkspaceBranch.NONE;
|
||||||
|
|
||||||
@ -12,9 +12,9 @@ public class TreeItemData<T> : ITreeItem<T>
|
|||||||
|
|
||||||
public bool IsChat { get; init; }
|
public bool IsChat { get; init; }
|
||||||
|
|
||||||
public T? Value { get; init; }
|
public string Path { get; init; } = string.Empty;
|
||||||
|
|
||||||
public bool Expandable { get; init; } = true;
|
public bool Expandable { get; init; } = true;
|
||||||
|
|
||||||
public HashSet<ITreeItem<T>> Children { get; init; } = [];
|
public HashSet<ITreeItem> Children { get; init; } = [];
|
||||||
}
|
}
|
@ -1,17 +1,17 @@
|
|||||||
<MudTreeView T="ITreeItem<string>" Items="@this.treeItems" MultiSelection="@false" Hover="@true" ExpandOnClick="@true">
|
<MudTreeView T="ITreeItem" Items="@this.treeItems" MultiSelection="@false" Hover="@true" ExpandOnClick="@true">
|
||||||
<ItemTemplate Context="item">
|
<ItemTemplate Context="item">
|
||||||
@switch (item)
|
@switch (item)
|
||||||
{
|
{
|
||||||
case TreeDivider<string>:
|
case TreeDivider:
|
||||||
<li style="min-height: 1em;">
|
<li style="min-height: 1em;">
|
||||||
<MudDivider Style="margin-top: 1em; width: 90%; border-width: 3pt;"/>
|
<MudDivider Style="margin-top: 1em; width: 90%; border-width: 3pt;"/>
|
||||||
</li>
|
</li>
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TreeItemData<string> treeItem:
|
case TreeItemData treeItem:
|
||||||
@if (treeItem.IsChat)
|
@if (treeItem.IsChat)
|
||||||
{
|
{
|
||||||
<MudTreeViewItem T="ITreeItem<string>" Icon="@treeItem.Icon" Value="@item" LoadingIconColor="@Color.Info" CanExpand="@treeItem.Expandable" Items="@treeItem.Children" OnClick="() => this.LoadChat(treeItem.Value)">
|
<MudTreeViewItem T="ITreeItem" Icon="@treeItem.Icon" Value="@item" LoadingIconColor="@Color.Info" CanExpand="@treeItem.Expandable" Items="@treeItem.Children" OnClick="() => this.LoadChat(treeItem.Path, true)">
|
||||||
<BodyContent>
|
<BodyContent>
|
||||||
<div style="display: grid; grid-template-columns: 1fr auto; align-items: center; width: 100%">
|
<div style="display: grid; grid-template-columns: 1fr auto; align-items: center; width: 100%">
|
||||||
<MudText Style="justify-self: start;">@treeItem.Text</MudText>
|
<MudText Style="justify-self: start;">@treeItem.Text</MudText>
|
||||||
@ -25,7 +25,7 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<MudTreeViewItem T="ITreeItem<string>" Icon="@treeItem.Icon" Value="@item" LoadingIconColor="@Color.Info" CanExpand="@treeItem.Expandable" Items="@treeItem.Children">
|
<MudTreeViewItem T="ITreeItem" Icon="@treeItem.Icon" Value="@item" LoadingIconColor="@Color.Info" CanExpand="@treeItem.Expandable" Items="@treeItem.Children">
|
||||||
<BodyContent>
|
<BodyContent>
|
||||||
<div style="display: grid; grid-template-columns: 1fr auto; align-items: center; width: 100%">
|
<div style="display: grid; grid-template-columns: 1fr auto; align-items: center; width: 100%">
|
||||||
<MudText Style="justify-self: start;">@treeItem.Text</MudText>
|
<MudText Style="justify-self: start;">@treeItem.Text</MudText>
|
||||||
@ -35,7 +35,7 @@
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TreeButton<string> treeButton:
|
case TreeButton treeButton:
|
||||||
<li>
|
<li>
|
||||||
<div class="mud-treeview-item-content" style="background-color: unset;">
|
<div class="mud-treeview-item-content" style="background-color: unset;">
|
||||||
<div class="mud-treeview-item-arrow"></div>
|
<div class="mud-treeview-item-arrow"></div>
|
||||||
|
@ -33,7 +33,7 @@ public partial class Workspaces : ComponentBase
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly HashSet<ITreeItem<string>> treeItems = new();
|
private readonly HashSet<ITreeItem> treeItems = new();
|
||||||
|
|
||||||
#region Overrides of ComponentBase
|
#region Overrides of ComponentBase
|
||||||
|
|
||||||
@ -55,33 +55,33 @@ public partial class Workspaces : ComponentBase
|
|||||||
private async Task LoadTreeItems()
|
private async Task LoadTreeItems()
|
||||||
{
|
{
|
||||||
this.treeItems.Clear();
|
this.treeItems.Clear();
|
||||||
this.treeItems.Add(new TreeItemData<string>
|
this.treeItems.Add(new TreeItemData
|
||||||
{
|
{
|
||||||
Depth = 0,
|
Depth = 0,
|
||||||
Branch = WorkspaceBranch.WORKSPACES,
|
Branch = WorkspaceBranch.WORKSPACES,
|
||||||
Text = "Workspaces",
|
Text = "Workspaces",
|
||||||
Icon = Icons.Material.Filled.Folder,
|
Icon = Icons.Material.Filled.Folder,
|
||||||
Expandable = true,
|
Expandable = true,
|
||||||
Value = "root",
|
Path = "root",
|
||||||
Children = await this.LoadWorkspaces(),
|
Children = await this.LoadWorkspaces(),
|
||||||
});
|
});
|
||||||
|
|
||||||
this.treeItems.Add(new TreeDivider<string>());
|
this.treeItems.Add(new TreeDivider());
|
||||||
this.treeItems.Add(new TreeItemData<string>
|
this.treeItems.Add(new TreeItemData
|
||||||
{
|
{
|
||||||
Depth = 0,
|
Depth = 0,
|
||||||
Branch = WorkspaceBranch.TEMPORARY_CHATS,
|
Branch = WorkspaceBranch.TEMPORARY_CHATS,
|
||||||
Text = "Temporary chats",
|
Text = "Temporary chats",
|
||||||
Icon = Icons.Material.Filled.Timer,
|
Icon = Icons.Material.Filled.Timer,
|
||||||
Expandable = true,
|
Expandable = true,
|
||||||
Value = "temp",
|
Path = "temp",
|
||||||
Children = await this.LoadTemporaryChats(),
|
Children = await this.LoadTemporaryChats(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<HashSet<ITreeItem<string>>> LoadTemporaryChats()
|
private async Task<HashSet<ITreeItem>> LoadTemporaryChats()
|
||||||
{
|
{
|
||||||
var tempChildren = new HashSet<ITreeItem<string>>();
|
var tempChildren = new HashSet<ITreeItem>();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Search for workspace folders in the data directory:
|
// Search for workspace folders in the data directory:
|
||||||
@ -100,7 +100,7 @@ public partial class Workspaces : ComponentBase
|
|||||||
var chatNamePath = Path.Join(tempChatDirPath, "name");
|
var chatNamePath = Path.Join(tempChatDirPath, "name");
|
||||||
var chatName = await File.ReadAllTextAsync(chatNamePath, Encoding.UTF8);
|
var chatName = await File.ReadAllTextAsync(chatNamePath, Encoding.UTF8);
|
||||||
|
|
||||||
tempChildren.Add(new TreeItemData<string>
|
tempChildren.Add(new TreeItemData
|
||||||
{
|
{
|
||||||
IsChat = true,
|
IsChat = true,
|
||||||
Depth = 1,
|
Depth = 1,
|
||||||
@ -108,7 +108,7 @@ public partial class Workspaces : ComponentBase
|
|||||||
Text = chatName,
|
Text = chatName,
|
||||||
Icon = Icons.Material.Filled.Timer,
|
Icon = Icons.Material.Filled.Timer,
|
||||||
Expandable = false,
|
Expandable = false,
|
||||||
Value = tempChatDirPath,
|
Path = tempChatDirPath,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,7 +117,7 @@ public partial class Workspaces : ComponentBase
|
|||||||
|
|
||||||
private async Task<HashSet<ITreeItem<string>>> LoadWorkspaces()
|
private async Task<HashSet<ITreeItem<string>>> LoadWorkspaces()
|
||||||
{
|
{
|
||||||
var workspaces = new HashSet<ITreeItem<string>>();
|
var workspaces = new HashSet<ITreeItem>();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Search for workspace folders in the data directory:
|
// Search for workspace folders in the data directory:
|
||||||
@ -136,7 +136,7 @@ public partial class Workspaces : ComponentBase
|
|||||||
var workspaceNamePath = Path.Join(workspaceDirPath, "name");
|
var workspaceNamePath = Path.Join(workspaceDirPath, "name");
|
||||||
var workspaceName = await File.ReadAllTextAsync(workspaceNamePath, Encoding.UTF8);
|
var workspaceName = await File.ReadAllTextAsync(workspaceNamePath, Encoding.UTF8);
|
||||||
|
|
||||||
workspaces.Add(new TreeItemData<string>
|
workspaces.Add(new TreeItemData
|
||||||
{
|
{
|
||||||
IsChat = false,
|
IsChat = false,
|
||||||
Depth = 1,
|
Depth = 1,
|
||||||
@ -144,18 +144,18 @@ public partial class Workspaces : ComponentBase
|
|||||||
Text = workspaceName,
|
Text = workspaceName,
|
||||||
Icon = Icons.Material.Filled.Description,
|
Icon = Icons.Material.Filled.Description,
|
||||||
Expandable = true,
|
Expandable = true,
|
||||||
Value = workspaceDirPath,
|
Path = workspaceDirPath,
|
||||||
Children = await this.LoadWorkspaceChats(workspaceDirPath),
|
Children = await this.LoadWorkspaceChats(workspaceDirPath),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
workspaces.Add(new TreeButton<string>(WorkspaceBranch.WORKSPACES, 1, "Add workspace",Icons.Material.Filled.Add));
|
workspaces.Add(new TreeButton(WorkspaceBranch.WORKSPACES, 1, "Add workspace",Icons.Material.Filled.Add));
|
||||||
return workspaces;
|
return workspaces;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<HashSet<ITreeItem<string>>> LoadWorkspaceChats(string workspacePath)
|
private async Task<HashSet<ITreeItem>> LoadWorkspaceChats(string workspacePath)
|
||||||
{
|
{
|
||||||
var workspaceChats = new HashSet<ITreeItem<string>>();
|
var workspaceChats = new HashSet<ITreeItem>();
|
||||||
|
|
||||||
// Enumerate the workspace directory:
|
// Enumerate the workspace directory:
|
||||||
foreach (var chatPath in Directory.EnumerateDirectories(workspacePath))
|
foreach (var chatPath in Directory.EnumerateDirectories(workspacePath))
|
||||||
@ -164,7 +164,7 @@ public partial class Workspaces : ComponentBase
|
|||||||
var chatNamePath = Path.Join(chatPath, "name");
|
var chatNamePath = Path.Join(chatPath, "name");
|
||||||
var chatName = await File.ReadAllTextAsync(chatNamePath, Encoding.UTF8);
|
var chatName = await File.ReadAllTextAsync(chatNamePath, Encoding.UTF8);
|
||||||
|
|
||||||
workspaceChats.Add(new TreeItemData<string>
|
workspaceChats.Add(new TreeItemData
|
||||||
{
|
{
|
||||||
IsChat = true,
|
IsChat = true,
|
||||||
Depth = 2,
|
Depth = 2,
|
||||||
@ -172,32 +172,32 @@ public partial class Workspaces : ComponentBase
|
|||||||
Text = chatName,
|
Text = chatName,
|
||||||
Icon = Icons.Material.Filled.Chat,
|
Icon = Icons.Material.Filled.Chat,
|
||||||
Expandable = false,
|
Expandable = false,
|
||||||
Value = chatPath,
|
Path = chatPath,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
workspaceChats.Add(new TreeButton<string>(WorkspaceBranch.WORKSPACES, 2, "Add chat",Icons.Material.Filled.Add));
|
workspaceChats.Add(new TreeButton(WorkspaceBranch.WORKSPACES, 2, "Add chat",Icons.Material.Filled.Add));
|
||||||
return workspaceChats;
|
return workspaceChats;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task StoreChat(ChatThread thread)
|
public async Task StoreChat(ChatThread chat)
|
||||||
{
|
{
|
||||||
string chatDirectory;
|
string chatDirectory;
|
||||||
if (thread.WorkspaceId == Guid.Empty)
|
if (chat.WorkspaceId == Guid.Empty)
|
||||||
chatDirectory = Path.Join(SettingsManager.DataDirectory, "tempChats", thread.ChatId.ToString());
|
chatDirectory = Path.Join(SettingsManager.DataDirectory, "tempChats", chat.ChatId.ToString());
|
||||||
else
|
else
|
||||||
chatDirectory = Path.Join(SettingsManager.DataDirectory, "workspaces", thread.WorkspaceId.ToString(), thread.ChatId.ToString());
|
chatDirectory = Path.Join(SettingsManager.DataDirectory, "workspaces", chat.WorkspaceId.ToString(), chat.ChatId.ToString());
|
||||||
|
|
||||||
// Ensure the directory exists:
|
// Ensure the directory exists:
|
||||||
Directory.CreateDirectory(chatDirectory);
|
Directory.CreateDirectory(chatDirectory);
|
||||||
|
|
||||||
// Save the chat name:
|
// Save the chat name:
|
||||||
var chatNamePath = Path.Join(chatDirectory, "name");
|
var chatNamePath = Path.Join(chatDirectory, "name");
|
||||||
await File.WriteAllTextAsync(chatNamePath, thread.Name);
|
await File.WriteAllTextAsync(chatNamePath, chat.Name);
|
||||||
|
|
||||||
// Save the thread as thread.json:
|
// Save the thread as thread.json:
|
||||||
var chatPath = Path.Join(chatDirectory, "thread.json");
|
var chatPath = Path.Join(chatDirectory, "thread.json");
|
||||||
await File.WriteAllTextAsync(chatPath, JsonSerializer.Serialize(thread, JSON_OPTIONS), Encoding.UTF8);
|
await File.WriteAllTextAsync(chatPath, JsonSerializer.Serialize(chat, JSON_OPTIONS), Encoding.UTF8);
|
||||||
|
|
||||||
// Reload the tree items:
|
// Reload the tree items:
|
||||||
await this.LoadTreeItems();
|
await this.LoadTreeItems();
|
||||||
|
Loading…
Reference in New Issue
Block a user