Improved input validation for the single input dialog (#541)

This commit is contained in:
Thorsten Sommer 2025-08-28 18:16:30 +02:00 committed by GitHub
parent e931e28ab1
commit 99dc2606aa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 77 additions and 18 deletions

View File

@ -2155,6 +2155,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2237618267"] = "Are you sure
-- Delete Chat -- Delete Chat
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2244038752"] = "Delete Chat" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2244038752"] = "Delete Chat"
-- Please enter a chat name.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2301651387"] = "Please enter a chat name."
-- Move to workspace -- Move to workspace
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2509305748"] = "Move to workspace" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2509305748"] = "Move to workspace"
@ -2167,6 +2170,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3045856778"] = "Move Chat to
-- Please enter a new or edit the name for your workspace '{0}': -- Please enter a new or edit the name for your workspace '{0}':
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T323280982"] = "Please enter a new or edit the name for your workspace '{0}':" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T323280982"] = "Please enter a new or edit the name for your workspace '{0}':"
-- Please enter a workspace name.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3288132732"] = "Please enter a workspace name."
-- Unnamed chat -- Unnamed chat
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3310482275"] = "Unnamed chat" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3310482275"] = "Unnamed chat"
@ -4135,6 +4141,9 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGWRITINGEMAILS::T4004
-- Chat name -- Chat name
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T1746586282"] = "Chat name" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T1746586282"] = "Chat name"
-- Please enter a value.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T3576780391"] = "Please enter a value."
-- Cancel -- Cancel
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T900713019"] = "Cancel" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T900713019"] = "Cancel"

View File

@ -396,12 +396,14 @@ public partial class Workspaces : MSGComponentBase
if (chat is null) if (chat is null)
return; return;
var dialogParameters = new DialogParameters var dialogParameters = new DialogParameters<SingleInputDialog>
{ {
{ "Message", string.Format(T("Please enter a new or edit the name for your chat '{0}':"), chat.Name) }, { x => x.Message, string.Format(T("Please enter a new or edit the name for your chat '{0}':"), chat.Name) },
{ "UserInput", chat.Name }, { x => x.UserInput, chat.Name },
{ "ConfirmText", T("Rename") }, { x => x.ConfirmText, T("Rename") },
{ "ConfirmColor", Color.Info }, { x => x.ConfirmColor, Color.Info },
{ x => x.AllowEmptyInput, false },
{ x => x.EmptyInputErrorMessage, T("Please enter a chat name.") },
}; };
var dialogReference = await this.DialogService.ShowAsync<SingleInputDialog>(T("Rename Chat"), dialogParameters, DialogOptions.FULLSCREEN); var dialogReference = await this.DialogService.ShowAsync<SingleInputDialog>(T("Rename Chat"), dialogParameters, DialogOptions.FULLSCREEN);
@ -428,12 +430,14 @@ public partial class Workspaces : MSGComponentBase
var workspaceId = Guid.Parse(Path.GetFileName(workspacePath)); var workspaceId = Guid.Parse(Path.GetFileName(workspacePath));
var workspaceName = await WorkspaceBehaviour.LoadWorkspaceName(workspaceId); var workspaceName = await WorkspaceBehaviour.LoadWorkspaceName(workspaceId);
var dialogParameters = new DialogParameters var dialogParameters = new DialogParameters<SingleInputDialog>
{ {
{ "Message", string.Format(T("Please enter a new or edit the name for your workspace '{0}':"), workspaceName) }, { x => x.Message, string.Format(T("Please enter a new or edit the name for your workspace '{0}':"), workspaceName) },
{ "UserInput", workspaceName }, { x => x.UserInput, workspaceName },
{ "ConfirmText", T("Rename") }, { x => x.ConfirmText, T("Rename") },
{ "ConfirmColor", Color.Info }, { x => x.ConfirmColor, Color.Info },
{ x => x.AllowEmptyInput, false },
{ x => x.EmptyInputErrorMessage, T("Please enter a workspace name.") },
}; };
var dialogReference = await this.DialogService.ShowAsync<SingleInputDialog>(T("Rename Workspace"), dialogParameters, DialogOptions.FULLSCREEN); var dialogReference = await this.DialogService.ShowAsync<SingleInputDialog>(T("Rename Workspace"), dialogParameters, DialogOptions.FULLSCREEN);
@ -449,12 +453,14 @@ public partial class Workspaces : MSGComponentBase
private async Task AddWorkspace() private async Task AddWorkspace()
{ {
var dialogParameters = new DialogParameters var dialogParameters = new DialogParameters<SingleInputDialog>
{ {
{ "Message", T("Please name your workspace:") }, { x => x.Message, T("Please name your workspace:") },
{ "UserInput", string.Empty }, { x => x.UserInput, string.Empty },
{ "ConfirmText", T("Add workspace") }, { x => x.ConfirmText, T("Add workspace") },
{ "ConfirmColor", Color.Info }, { x => x.ConfirmColor, Color.Info },
{ x => x.AllowEmptyInput, false },
{ x => x.EmptyInputErrorMessage, T("Please enter a workspace name.") },
}; };
var dialogReference = await this.DialogService.ShowAsync<SingleInputDialog>(T("Add Workspace"), dialogParameters, DialogOptions.FULLSCREEN); var dialogReference = await this.DialogService.ShowAsync<SingleInputDialog>(T("Add Workspace"), dialogParameters, DialogOptions.FULLSCREEN);

View File

@ -4,7 +4,9 @@
<MudText Typo="Typo.body1"> <MudText Typo="Typo.body1">
@this.Message @this.Message
</MudText> </MudText>
<MudTextField T="string" @bind-Text="@this.UserInput" Variant="Variant.Outlined" AutoGrow="@false" Lines="1" Label="@T("Chat name")" AutoFocus="@true" UserAttributes="@USER_INPUT_ATTRIBUTES"/> <MudForm @ref="this.form" Class="mt-4">
<MudTextField T="string" @bind-Text="@this.UserInput" Variant="Variant.Outlined" AutoGrow="@false" Lines="1" Label="@T("Chat name")" AutoFocus="@true" UserAttributes="@USER_INPUT_ATTRIBUTES" Validation="@this.ValidateUserInput" />
</MudForm>
</DialogContent> </DialogContent>
<DialogActions> <DialogActions>
<MudButton OnClick="@this.Cancel" Variant="Variant.Filled"> <MudButton OnClick="@this.Cancel" Variant="Variant.Filled">

View File

@ -21,8 +21,16 @@ public partial class SingleInputDialog : MSGComponentBase
[Parameter] [Parameter]
public Color ConfirmColor { get; set; } = Color.Error; public Color ConfirmColor { get; set; } = Color.Error;
[Parameter]
public bool AllowEmptyInput { get; set; }
[Parameter]
public string EmptyInputErrorMessage { get; set; } = string.Empty;
private static readonly Dictionary<string, object?> USER_INPUT_ATTRIBUTES = new(); private static readonly Dictionary<string, object?> USER_INPUT_ATTRIBUTES = new();
private MudForm form = null!;
#region Overrides of ComponentBase #region Overrides of ComponentBase
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
@ -34,7 +42,22 @@ public partial class SingleInputDialog : MSGComponentBase
#endregion #endregion
private string? ValidateUserInput(string? value)
{
if (!this.AllowEmptyInput && string.IsNullOrWhiteSpace(value))
return string.IsNullOrWhiteSpace(this.EmptyInputErrorMessage) ? T("Please enter a value.") : this.EmptyInputErrorMessage;
return null;
}
private void Cancel() => this.MudDialog.Cancel(); private void Cancel() => this.MudDialog.Cancel();
private void Confirm() => this.MudDialog.Close(DialogResult.Ok(this.UserInput)); private async Task Confirm()
{
await this.form.Validate();
if(!this.form.IsValid)
return;
this.MudDialog.Close(DialogResult.Ok(this.UserInput));
}
} }

View File

@ -2157,6 +2157,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2237618267"] = "Möchten Sie
-- Delete Chat -- Delete Chat
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2244038752"] = "Chat löschen" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2244038752"] = "Chat löschen"
-- Please enter a chat name.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2301651387"] = "Bitte geben Sie einen Namen für diesen Chat ein."
-- Move to workspace -- Move to workspace
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2509305748"] = "In einen Arbeitsbereich verschieben" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2509305748"] = "In einen Arbeitsbereich verschieben"
@ -2169,6 +2172,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3045856778"] = "Chat in den
-- Please enter a new or edit the name for your workspace '{0}': -- Please enter a new or edit the name for your workspace '{0}':
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T323280982"] = "Bitte geben Sie einen neuen Namen für ihren Arbeitsbereich „{0}“ ein oder bearbeiten Sie ihn:" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T323280982"] = "Bitte geben Sie einen neuen Namen für ihren Arbeitsbereich „{0}“ ein oder bearbeiten Sie ihn:"
-- Please enter a workspace name.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3288132732"] = "Bitte geben Sie einen Namen für diesen Arbeitsbereich ein."
-- Unnamed chat -- Unnamed chat
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3310482275"] = "Unbenannter Chat" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3310482275"] = "Unbenannter Chat"
@ -4137,6 +4143,9 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGWRITINGEMAILS::T4004
-- Chat name -- Chat name
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T1746586282"] = "Chat-Name" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T1746586282"] = "Chat-Name"
-- Please enter a value.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T3576780391"] = "Bitte geben Sie einen Wert ein."
-- Cancel -- Cancel
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T900713019"] = "Abbrechen" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T900713019"] = "Abbrechen"

View File

@ -2157,6 +2157,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2237618267"] = "Are you sure
-- Delete Chat -- Delete Chat
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2244038752"] = "Delete Chat" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2244038752"] = "Delete Chat"
-- Please enter a chat name.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2301651387"] = "Please enter a chat name."
-- Move to workspace -- Move to workspace
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2509305748"] = "Move to workspace" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T2509305748"] = "Move to workspace"
@ -2169,6 +2172,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3045856778"] = "Move Chat to
-- Please enter a new or edit the name for your workspace '{0}': -- Please enter a new or edit the name for your workspace '{0}':
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T323280982"] = "Please enter a new or edit the name for your workspace '{0}':" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T323280982"] = "Please enter a new or edit the name for your workspace '{0}':"
-- Please enter a workspace name.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3288132732"] = "Please enter a workspace name."
-- Unnamed chat -- Unnamed chat
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3310482275"] = "Unnamed chat" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::WORKSPACES::T3310482275"] = "Unnamed chat"
@ -4137,6 +4143,9 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGWRITINGEMAILS::T4004
-- Chat name -- Chat name
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T1746586282"] = "Chat name" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T1746586282"] = "Chat name"
-- Please enter a value.
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T3576780391"] = "Please enter a value."
-- Cancel -- Cancel
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T900713019"] = "Cancel" UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SINGLEINPUTDIALOG::T900713019"] = "Cancel"

View File

@ -4,6 +4,7 @@
- Added the ability to control the update installation behavior by configuration plugins. - Added the ability to control the update installation behavior by configuration plugins.
- Improved memory usage in several areas of the app. - Improved memory usage in several areas of the app.
- Improved plugin management for configuration plugins so that hot reload detects when a provider or chat template has been removed. - Improved plugin management for configuration plugins so that hot reload detects when a provider or chat template has been removed.
- Improved the dialog for naming chats and workspaces to ensure valid inputs are entered.
- Changed the configuration plugin setting name for how often to check for updates from `UpdateBehavior` to `UpdateInterval`. - Changed the configuration plugin setting name for how often to check for updates from `UpdateBehavior` to `UpdateInterval`.
- Fixed a bug in various assistants where some text fields were not reset when resetting. - Fixed a bug in various assistants where some text fields were not reset when resetting.
- Fixed a rare chat-related bug that could occur when a workspace was not created correctly. Thank you, Naomi, for reporting this issue. - Fixed a rare chat-related bug that could occur when a workspace was not created correctly. Thank you, Naomi, for reporting this issue.