@using MudBlazor @using RobotNet10.ScriptEditor.Models @using RobotNet10.ScriptEngine.Shared Create Mission: @MissionName @if (Parameters == null || Parameters.Length == 0) { This mission has no parameters. } else { @foreach (var param in Parameters) { @switch (param.Type) { case "System.Boolean": break; case "System.Byte": break; case "System.SByte": break; case "System.Int16": break; case "System.UInt16": break; case "System.Int32": break; case "System.UInt32": break; case "System.Int64": break; case "System.UInt64": break; case "System.Single": break; case "System.Double": break; case "System.Decimal": break; case "System.String": break; case "System.Char": break; case "System.Threading.CancellationToken": <CancellationToken> break; default: Unsupport parameter with type @param.Type break; } } } Cancel Create @code { [CascadingParameter] IMudDialogInstance Dialog { get; set; } = null!; [Parameter, EditorRequired] public ScriptMissionDto Model { get; set; } = default!; public string MissionName => Model.Name; private ScriptMissionParameterValueModel[] Parameters = []; private bool IsValid => Parameters.All(p => string.IsNullOrEmpty(p.Errors)); protected override void OnAfterRender(bool firstRender) { base.OnAfterRender(firstRender); if (firstRender) { Parameters = [.. Model.Parameters.Select(p => new ScriptMissionParameterValueModel(p.Name, p.Type, p.Default ?? ""))]; for (int i = 0; i < Parameters.Length; i++) { ValidateParameter(i); } StateHasChanged(); } } private bool HasDefaultValue(int index) { if (index < 0 || index >= Parameters.Length) return false; return !string.IsNullOrEmpty(Parameters[index].Default); } private string GetHelperText(string typeName) { var type = ScriptHelpers.ResolveTypeFromString(typeName); if (type == null) return ""; return type switch { _ when type == typeof(bool) => "Enter 'true' or 'false'", _ when type == typeof(int) => "Enter an integer value", _ when type == typeof(long) => "Enter a long integer value", _ when type == typeof(float) => "Enter a float value (e.g., 3.14f)", _ when type == typeof(double) => "Enter a double value (e.g., 3.14)", _ when type == typeof(decimal) => "Enter a decimal value (e.g., 3.14)", _ when type == typeof(char) => "Enter a single character", _ when type == typeof(string) => "Enter a string value", _ when type.IsEnum => $"Enter one of: {string.Join(", ", Enum.GetNames(type))}", _ => "Enter a valid value" }; } private void ValidateParameter(int index) { if (index < 0 || index >= Parameters.Length) return; if(Parameters[index].Type == "System.Threading.CancellationToken") { // No validation needed return; } Parameters[index].Errors = string.Empty; var param = Parameters[index]; var value = Parameters[index].ToString(); // Allow empty if has default value if (string.IsNullOrWhiteSpace(value) && !string.IsNullOrEmpty(param.Default)) { return; } if (string.IsNullOrWhiteSpace(value) && string.IsNullOrEmpty(param.Default)) { Parameters[index].Errors = "Value is required"; return; } var type = ScriptHelpers.ResolveTypeFromString(param.Type); if (type == null) { Parameters[index].Errors = "Unknown type"; return; } try { if (type.IsEnum) { Enum.Parse(type, value.Trim(), ignoreCase: true); } else if (!ScriptHelpers.ResolveValueFromString(value.Trim(), type, out _)) { Parameters[index].Errors = $"Invalid value for type {param.Type}"; } } catch (ArgumentException) { Parameters[index].Errors = $"Invalid value for type {param.Type}"; } catch (Exception) { Parameters[index].Errors = $"Failed to validate value for type {param.Type}"; } } private void Cancel() => Dialog.Cancel(); private void Submit() { if (!IsValid) return; var parameters = new Dictionary(); for (int i = 0; i < Parameters.Length; i++) { var value = Parameters[i].ToString(); // Use default if empty and default exists if (string.IsNullOrWhiteSpace(value) && !string.IsNullOrEmpty(Parameters[i].Default)) { value = Parameters[i].Default; } parameters[Parameters[i].Name] = value ?? string.Empty; } Dialog.Close(DialogResult.Ok(parameters)); } }