Improved the dialog for moving chats into workspaces (#796)
Build and Release / Determine run mode (push) Has been cancelled
Build and Release / Read metadata (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg,app,updater, dmg) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis,updater, nsis) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage,updater, appimage) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg,app,updater, dmg) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis,updater, nsis) (push) Has been cancelled
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage,updater, appimage) (push) Has been cancelled
Build and Release / Prepare & create release (push) Has been cancelled
Build and Release / Publish release (push) Has been cancelled

This commit is contained in:
Thorsten Sommer authored and GitHub committed 2026-06-06 10:06:41 +02:00
1 parent 0b41f5eb96
commit 102b344557
13 files changed
+489 -37

No files matched your search

@@ -3,7 +3,6 @@ using System.Text.Json;
using AIStudio.Chat;
using AIStudio.Dialogs;
using AIStudio.Settings;
using AIStudio.Tools.AIJobs;
using Microsoft.AspNetCore.Components;
@@ -57,7 +56,7 @@ public partial class Workspaces : MSGComponentBase
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
this.ApplyFilters([], [ Event.AI_JOB_CHANGED, Event.AI_JOB_FINISHED, Event.CHAT_GENERATION_CHANGED ]);
this.ApplyFilters([], [ Event.AI_JOB_CHANGED, Event.AI_JOB_FINISHED, Event.CHAT_GENERATION_CHANGED, Event.WORKSPACE_CREATED ]);
_ = this.LoadTreeItemsAsync(startPrefetch: true);
}
@@ -101,6 +100,27 @@ public partial class Workspaces : MSGComponentBase
private string GetAddChatToWorkspaceTooltip(string workspaceName) => string.Format(T("Start a new chat in workspace '{0}'"), workspaceName);
private async Task<Func<string?, string?>> CreateWorkspaceNameValidationAsync(Guid excludedWorkspaceId = default, string? originalWorkspaceName = null)
{
var snapshot = await WorkspaceBehaviour.GetOrLoadWorkspaceTreeShellAsync();
return workspaceName =>
{
var normalizedWorkspaceName = WorkspaceBehaviour.NormalizeWorkspaceName(workspaceName ?? string.Empty);
if (string.IsNullOrWhiteSpace(normalizedWorkspaceName))
return null;
if (!string.IsNullOrWhiteSpace(originalWorkspaceName) &&
string.Equals(WorkspaceBehaviour.NormalizeWorkspaceName(originalWorkspaceName), normalizedWorkspaceName, StringComparison.OrdinalIgnoreCase))
return null;
var nameExists = snapshot.Workspaces.Any(workspace =>
workspace.WorkspaceId != excludedWorkspaceId &&
string.Equals(WorkspaceBehaviour.NormalizeWorkspaceName(workspace.Name), normalizedWorkspaceName, StringComparison.OrdinalIgnoreCase));
return nameExists ? T("There is already a workspace with this name. Please choose a different name.") : null;
};
}
private void BuildTreeItems(WorkspaceTreeCacheSnapshot snapshot)
{
this.treeItems.Clear();
@@ -720,6 +740,7 @@ public partial class Workspaces : MSGComponentBase
{ x => x.ConfirmColor, Color.Info },
{ x => x.AllowEmptyInput, false },
{ x => x.EmptyInputErrorMessage, T("Please enter a workspace name.") },
{ x => x.AdditionalValidation, await this.CreateWorkspaceNameValidationAsync(workspaceId, workspaceName) },
};
var dialogReference = await this.DialogService.ShowAsync<SingleInputDialog>(T("Rename Workspace"), dialogParameters, DialogOptions.FULLSCREEN);
@@ -728,9 +749,10 @@ public partial class Workspaces : MSGComponentBase
return;
var alteredWorkspaceName = (dialogResult.Data as string)!;
var workspaceNamePath = Path.Join(workspacePath, "name");
await File.WriteAllTextAsync(workspaceNamePath, alteredWorkspaceName, Encoding.UTF8);
await WorkspaceBehaviour.UpdateWorkspaceNameInCacheAsync(workspaceId, alteredWorkspaceName);
if (!await WorkspaceBehaviour.RenameWorkspaceAsync(workspaceId, alteredWorkspaceName))
return;
await this.SendMessage(Event.WORKSPACE_RENAMED, workspaceId);
await this.LoadTreeItemsAsync(startPrefetch: false);
}
@@ -745,6 +767,7 @@ public partial class Workspaces : MSGComponentBase
{ x => x.ConfirmColor, Color.Info },
{ x => x.AllowEmptyInput, false },
{ x => x.EmptyInputErrorMessage, T("Please enter a workspace name.") },
{ x => x.AdditionalValidation, await this.CreateWorkspaceNameValidationAsync() },
};
var dialogReference = await this.DialogService.ShowAsync<SingleInputDialog>(T("Add Workspace"), dialogParameters, DialogOptions.FULLSCREEN);
@@ -752,14 +775,10 @@ public partial class Workspaces : MSGComponentBase
if (dialogResult is null || dialogResult.Canceled)
return;
var workspaceId = Guid.NewGuid();
var workspacePath = Path.Join(SettingsManager.DataDirectory, "workspaces", workspaceId.ToString());
Directory.CreateDirectory(workspacePath);
var workspaceName = (dialogResult.Data as string)!;
var workspaceNamePath = Path.Join(workspacePath, "name");
await File.WriteAllTextAsync(workspaceNamePath, workspaceName, Encoding.UTF8);
await WorkspaceBehaviour.AddWorkspaceToCacheAsync(workspaceId, workspacePath, workspaceName);
var result = await WorkspaceBehaviour.TryCreateWorkspaceAsync(workspaceName);
if (!result.Success)
return;
await this.LoadTreeItemsAsync(startPrefetch: false);
}
@@ -804,7 +823,7 @@ public partial class Workspaces : MSGComponentBase
{ x => x.ConfirmText, T("Move chat") },
};
var dialogReference = await this.DialogService.ShowAsync<WorkspaceSelectionDialog>(T("Move Chat to Workspace"), dialogParameters, DialogOptions.FULLSCREEN);
var dialogReference = await this.DialogService.ShowAsync<WorkspaceSelectionDialog>(T("Move Chat to Workspace"), dialogParameters, DialogOptions.FULLSCREEN_MANUAL_ESCAPE);
var dialogResult = await dialogReference.Result;
if (dialogResult is null || dialogResult.Canceled)
return;
@@ -868,6 +887,10 @@ public partial class Workspaces : MSGComponentBase
await this.ForceRefreshFromDiskAsync();
break;
case Event.WORKSPACE_CREATED:
await this.LoadTreeItemsAsync(startPrefetch: false);
break;
case Event.AI_JOB_CHANGED:
case Event.AI_JOB_FINISHED:
case Event.CHAT_GENERATION_CHANGED: