Refactor workspace creation logic and update UI for new workspace functionality

This commit is contained in:
Thorsten Sommer 2026-06-05 11:05:25 +02:00
parent 6c48a7fb7c
commit ab6cfb0218
Signed by untrusted user who does not match committer: tsommer
GPG Key ID: 371BBA77A02C0108
7 changed files with 57 additions and 38 deletions

View File

@ -5797,6 +5797,9 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::UPDATEDIALOG::T25417398"] = "Update from v{0
-- Install later
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::UPDATEDIALOG::T2936430090"] = "Install later"
-- Create new workspace
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::WORKSPACESELECTIONDIALOG::T1541251414"] = "Create new workspace"
-- Add workspace
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::WORKSPACESELECTIONDIALOG::T1586005241"] = "Add workspace"
@ -5809,9 +5812,6 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::WORKSPACESELECTIONDIALOG::T3249036008"] = "T
-- Please enter a workspace name.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::WORKSPACESELECTIONDIALOG::T3288132732"] = "Please enter a workspace name."
-- Create a new workspace
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::WORKSPACESELECTIONDIALOG::T591103325"] = "Create a new workspace"
-- Cancel
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::WORKSPACESELECTIONDIALOG::T900713019"] = "Cancel"

View File

@ -775,7 +775,8 @@ public partial class Workspaces : MSGComponentBase
return;
var workspaceName = (dialogResult.Data as string)!;
if (await WorkspaceBehaviour.CreateWorkspaceAsync(workspaceName) is null)
var result = await WorkspaceBehaviour.TryCreateWorkspaceAsync(workspaceName);
if (!result.Success)
return;
await this.LoadTreeItemsAsync(startPrefetch: false);

View File

@ -11,26 +11,32 @@
}
</MudList>
<MudDivider Class="my-4"/>
<MudText Typo="Typo.body2">
@T("Create a new workspace")
</MudText>
<MudForm @ref="this.createWorkspaceForm" Class="mt-2">
<MudStack Row="@true" AlignItems="AlignItems.Start" Wrap="Wrap.NoWrap" Spacing="1">
<MudTextField T="string"
@bind-Text="@this.newWorkspaceName"
Variant="Variant.Outlined"
AutoGrow="@false"
Lines="1"
Label="@T("Workspace name")"
Immediate="@true"
Disabled="@this.isCreatingWorkspace"
OnKeyDown="@this.HandleNewWorkspaceNameKeyDown"
Validation="@this.ValidateNewWorkspaceName" />
<MudTooltip Text="@T("Add workspace")">
<MudIconButton Icon="@Icons.Material.Filled.LibraryAdd" Color="Color.Info" Disabled="@this.isCreatingWorkspace" OnClick="@this.CreateWorkspaceAsync"/>
</MudTooltip>
</MudStack>
</MudForm>
@if (this.showCreateWorkspaceForm)
{
<MudForm @ref="this.createWorkspaceForm">
<MudStack Row="@true" AlignItems="AlignItems.Start" Wrap="Wrap.NoWrap" Spacing="1">
<MudTextField T="string"
@bind-Text="@this.newWorkspaceName"
Variant="Variant.Outlined"
AutoGrow="@false"
Lines="1"
Label="@T("Workspace name")"
Immediate="@true"
Disabled="@this.isCreatingWorkspace"
OnKeyDown="@this.HandleNewWorkspaceNameKeyDown"
Validation="@this.ValidateNewWorkspaceName" />
<MudTooltip Text="@T("Add workspace")">
<MudIconButton Icon="@Icons.Material.Filled.LibraryAdd" Color="Color.Info" Disabled="@this.isCreatingWorkspace" OnClick="@this.CreateWorkspaceAsync"/>
</MudTooltip>
</MudStack>
</MudForm>
}
else
{
<MudButton StartIcon="@Icons.Material.Filled.LibraryAdd" Variant="Variant.Filled" OnClick="@this.ShowCreateWorkspaceForm">
@T("Create new workspace")
</MudButton>
}
</DialogContent>
<DialogActions>
<MudButton OnClick="@this.Cancel" Variant="Variant.Filled">

View File

@ -26,6 +26,7 @@ public partial class WorkspaceSelectionDialog : MSGComponentBase
private Guid selectedWorkspace;
private string newWorkspaceName = string.Empty;
private bool isCreatingWorkspace;
private bool showCreateWorkspaceForm;
private string? createWorkspaceError;
private string? createWorkspaceErrorName;
@ -79,6 +80,14 @@ public partial class WorkspaceSelectionDialog : MSGComponentBase
await this.CreateWorkspaceAsync();
}
private void ShowCreateWorkspaceForm()
{
this.createWorkspaceError = null;
this.createWorkspaceErrorName = null;
this.newWorkspaceName = string.Empty;
this.showCreateWorkspaceForm = true;
}
private async Task CreateWorkspaceAsync()
{
this.createWorkspaceError = null;
@ -90,8 +99,8 @@ public partial class WorkspaceSelectionDialog : MSGComponentBase
this.isCreatingWorkspace = true;
try
{
var workspace = await WorkspaceBehaviour.CreateWorkspaceAsync(this.newWorkspaceName);
if (workspace is null)
var result = await WorkspaceBehaviour.TryCreateWorkspaceAsync(this.newWorkspaceName);
if (!result.Success)
{
this.createWorkspaceError = T("There is already a workspace with this name. Please choose a different name.");
this.createWorkspaceErrorName = WorkspaceBehaviour.NormalizeWorkspaceName(this.newWorkspaceName);
@ -99,10 +108,11 @@ public partial class WorkspaceSelectionDialog : MSGComponentBase
return;
}
this.workspaces.Add(new(workspace.Value.WorkspaceId, workspace.Value.Name));
this.selectedWorkspace = workspace.Value.WorkspaceId;
this.workspaces.Add(new(result.Workspace.WorkspaceId, result.Workspace.Name));
this.selectedWorkspace = result.Workspace.WorkspaceId;
this.newWorkspaceName = string.Empty;
this.createWorkspaceForm.ResetValidation();
this.showCreateWorkspaceForm = false;
}
finally
{

View File

@ -5799,6 +5799,9 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::UPDATEDIALOG::T25417398"] = "Aktualisieren v
-- Install later
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::UPDATEDIALOG::T2936430090"] = "Später installieren"
-- Create new workspace
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::WORKSPACESELECTIONDIALOG::T1541251414"] = "Neuen Arbeitsbereich erstellen"
-- Add workspace
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::WORKSPACESELECTIONDIALOG::T1586005241"] = "Arbeitsbereich hinzufügen"
@ -5811,9 +5814,6 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::WORKSPACESELECTIONDIALOG::T3249036008"] = "E
-- Please enter a workspace name.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::WORKSPACESELECTIONDIALOG::T3288132732"] = "Bitte geben Sie einen Namen für diesen Arbeitsbereich ein."
-- Create a new workspace
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::WORKSPACESELECTIONDIALOG::T591103325"] = "Neuen Arbeitsbereich erstellen"
-- Cancel
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::WORKSPACESELECTIONDIALOG::T900713019"] = "Abbrechen"

View File

@ -5799,6 +5799,9 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::UPDATEDIALOG::T25417398"] = "Update from v{0
-- Install later
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::UPDATEDIALOG::T2936430090"] = "Install later"
-- Create new workspace
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::WORKSPACESELECTIONDIALOG::T1541251414"] = "Create new workspace"
-- Add workspace
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::WORKSPACESELECTIONDIALOG::T1586005241"] = "Add workspace"
@ -5811,9 +5814,6 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::WORKSPACESELECTIONDIALOG::T3249036008"] = "T
-- Please enter a workspace name.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::WORKSPACESELECTIONDIALOG::T3288132732"] = "Please enter a workspace name."
-- Create a new workspace
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::WORKSPACESELECTIONDIALOG::T591103325"] = "Create a new workspace"
-- Cancel
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::WORKSPACESELECTIONDIALOG::T900713019"] = "Cancel"

View File

@ -12,6 +12,8 @@ namespace AIStudio.Tools;
public static class WorkspaceBehaviour
{
public readonly record struct TryCreateWorkspaceResult(bool Success, WorkspaceTreeWorkspace Workspace);
private sealed class WorkspaceChatCacheEntry
{
public Guid WorkspaceId { get; init; }
@ -615,18 +617,18 @@ public static class WorkspaceBehaviour
}
}
public static async Task<WorkspaceTreeWorkspace?> CreateWorkspaceAsync(string workspaceName)
public static async Task<TryCreateWorkspaceResult> TryCreateWorkspaceAsync(string workspaceName)
{
var normalizedWorkspaceName = NormalizeWorkspaceName(workspaceName);
if (string.IsNullOrWhiteSpace(normalizedWorkspaceName))
return null;
return new(false, default);
await WORKSPACE_TREE_CACHE_SEMAPHORE.WaitAsync();
try
{
await EnsureTreeShellLoadedCoreAsync();
if (WorkspaceNameExistsCore(normalizedWorkspaceName))
return null;
return new(false, default);
var workspaceId = Guid.NewGuid();
var workspacePath = Path.Join(WORKSPACE_ROOT_DIRECTORY, workspaceId.ToString());
@ -646,7 +648,7 @@ public static class WorkspaceBehaviour
WORKSPACE_TREE_CACHE.Workspaces[workspaceId] = workspace;
WORKSPACE_TREE_CACHE.WorkspaceOrder.Add(workspaceId);
return ToPublicWorkspace(workspace);
return new(true, ToPublicWorkspace(workspace));
}
finally
{