From b9fec9f30310d2c91f5c78a8d810d59b35b7dd9c Mon Sep 17 00:00:00 2001 From: Florian Gilde Date: Tue, 17 Dec 2024 13:26:25 +0100 Subject: [PATCH 1/2] try improve close --- .../Helper/MudDialogInstanceExtensions.cs | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/MudBlazor.Extensions/Helper/MudDialogInstanceExtensions.cs b/MudBlazor.Extensions/Helper/MudDialogInstanceExtensions.cs index f0426884..c8d34faa 100644 --- a/MudBlazor.Extensions/Helper/MudDialogInstanceExtensions.cs +++ b/MudBlazor.Extensions/Helper/MudDialogInstanceExtensions.cs @@ -5,32 +5,33 @@ namespace MudBlazor.Extensions.Helper; public static class MudDialogInstanceExtensions { public static void CloseAnimated(this MudDialogInstance instance, IJSRuntime jsRuntime = null) - => AnimateClose(instance, jsRuntime).ContinueWith(_ => instance.Close(), TaskScheduler.FromCurrentSynchronizationContext()); + => _ = AnimateClose(instance, (i) => { i.Close(); return Task.CompletedTask; }, jsRuntime); public static void CancelAnimated(this MudDialogInstance instance, IJSRuntime jsRuntime = null) - => AnimateClose(instance, jsRuntime).ContinueWith(_ => instance.Cancel(), TaskScheduler.FromCurrentSynchronizationContext()); + => _ = AnimateClose(instance, (i) => { i.Cancel(); return Task.CompletedTask; }, jsRuntime); public static void CloseAnimated(this MudDialogInstance instance, DialogResult result, IJSRuntime jsRuntime = null) - => AnimateClose(instance, jsRuntime).ContinueWith(_ => instance.Close(result), TaskScheduler.FromCurrentSynchronizationContext()); - + => _ = AnimateClose(instance, (i) => { i.Close(result); return Task.CompletedTask; }, jsRuntime); public static void CloseAnimated(this MudDialogInstance instance, T result, IJSRuntime jsRuntime = null) - => AnimateClose(instance, jsRuntime).ContinueWith(_ => instance.Close(result), TaskScheduler.FromCurrentSynchronizationContext()); + => _ = AnimateClose(instance, (i) => { i.Close(result); return Task.CompletedTask; }, jsRuntime); public static void CloseAnimatedIf(this MudDialogInstance instance, IJSRuntime jsRuntime = null) - => AnimateClose(instance, jsRuntime, true).ContinueWith(_ => instance.Close(), TaskScheduler.FromCurrentSynchronizationContext()); + => _ = AnimateClose(instance, (i) => { i.Close(); return Task.CompletedTask; }, jsRuntime, true); public static void CancelAnimatedIf(this MudDialogInstance instance, IJSRuntime jsRuntime = null) - => AnimateClose(instance, jsRuntime, true).ContinueWith(_ => instance.Cancel(), TaskScheduler.FromCurrentSynchronizationContext()); + => _ = AnimateClose(instance, (i) => { i.Cancel(); return Task.CompletedTask; }, jsRuntime, true); public static void CloseAnimatedIf(this MudDialogInstance instance, DialogResult result, IJSRuntime jsRuntime = null) - => AnimateClose(instance, jsRuntime, true).ContinueWith(_ => instance.Close(result), TaskScheduler.FromCurrentSynchronizationContext()); + => _ = AnimateClose(instance, (i) => { i.Close(result); return Task.CompletedTask; }, jsRuntime, true); public static void CloseAnimatedIf(this MudDialogInstance instance, T result, IJSRuntime jsRuntime = null) - => AnimateClose(instance, jsRuntime, true).ContinueWith(_ => instance.Close(result), TaskScheduler.FromCurrentSynchronizationContext()); + => _ = AnimateClose(instance, (i) => { i.Close(result); return Task.CompletedTask; }, jsRuntime, true); - private static Task AnimateClose(this MudDialogInstance instance, IJSRuntime jsRuntime = null, bool checkOptions = false) + private static async Task AnimateClose(this MudDialogInstance instance, Func callback, IJSRuntime jsRuntime = null, bool checkOptions = false) { var dialogId = DialogReferenceExtensions.PrepareDialogId(instance.Id); - return (jsRuntime ?? JsImportHelper.GetInitializedJsRuntime()).InvokeVoidAsync("MudBlazorExtensions.closeDialogAnimated", dialogId, checkOptions).AsTask(); + await (jsRuntime ?? JsImportHelper.GetInitializedJsRuntime()).InvokeVoidAsync("MudBlazorExtensions.closeDialogAnimated", dialogId, checkOptions); + await callback(instance); } + } From bcc04217e988a8bfdf54fd53434632e83ea280e2 Mon Sep 17 00:00:00 2001 From: Florian Gilde Date: Tue, 17 Dec 2024 14:54:03 +0100 Subject: [PATCH 2/2] Add AutoFocus to ObjectEdit and pass correct runtime for close animations --- .../Components/MudExMessageDialog.razor.cs | 2 +- .../ObjectEdit/MudExObjectEdit.razor | 1 + .../ObjectEdit/MudExObjectEdit.razor.cs | 83 +++++++++++-------- .../ObjectEdit/MudExObjectEditDialog.razor.cs | 5 +- .../MudExObjectEditExtensions.PropertyMeta.cs | 9 ++ .../ObjectEdit/MudExPropertyEdit.razor | 1 + .../ObjectEdit/MudExPropertyEdit.razor.cs | 13 +++ .../Options/ObjectEditPropertyMetaSettings.cs | 7 +- MudBlazor.Extensions/Docs/CHANGELOG.md | 4 + .../Helper/MudDialogInstanceExtensions.cs | 13 ++- .../MudBlazorExtensionsMiddleware.cs | 33 -------- .../MudBlazor.Extensions.csproj | 1 + ...MudBlazorExtensionsMiddlewareExtensions.cs | 20 ----- MudBlazor.Extensions/MudExWebApp.cs | 45 ++++++++++ .../wwwroot/docs/MudBlazor.Extensions.xml | 22 +++++ README.md | 8 +- .../MainSample.ServerSide/Pages/_Host.cshtml | 2 +- Samples/MainSample.ServerSide/Program.cs | 5 +- .../Pages/Page_ObjectEditConfigured.razor | 5 +- .../Pages/Page_StructuredDataEdit.razor | 7 +- .../Shared/ProgrammingSkillSelect.razor | 2 +- 21 files changed, 187 insertions(+), 101 deletions(-) delete mode 100644 MudBlazor.Extensions/Middleware/MudBlazorExtensionsMiddleware.cs delete mode 100644 MudBlazor.Extensions/MudBlazorExtensionsMiddlewareExtensions.cs create mode 100644 MudBlazor.Extensions/MudExWebApp.cs diff --git a/MudBlazor.Extensions/Components/MudExMessageDialog.razor.cs b/MudBlazor.Extensions/Components/MudExMessageDialog.razor.cs index b03474d7..41860529 100644 --- a/MudBlazor.Extensions/Components/MudExMessageDialog.razor.cs +++ b/MudBlazor.Extensions/Components/MudExMessageDialog.razor.cs @@ -190,5 +190,5 @@ void Submit(DialogResult result) /// /// Cancels the dialog /// - void Cancel() => MudDialog.CloseAnimatedIf(); + void Cancel() => MudDialog.CloseAnimatedIf(JsRuntime); } diff --git a/MudBlazor.Extensions/Components/ObjectEdit/MudExObjectEdit.razor b/MudBlazor.Extensions/Components/ObjectEdit/MudExObjectEdit.razor index 29a1b155..0d34f596 100644 --- a/MudBlazor.Extensions/Components/ObjectEdit/MudExObjectEdit.razor +++ b/MudBlazor.Extensions/Components/ObjectEdit/MudExObjectEdit.razor @@ -172,6 +172,7 @@ return @ /// Returns true if we have a registration for the current object that then uses the registered component /// protected bool HasRegistrationForWholeObject => RenderWithType != null; - + /// /// Is true if currently is an internal Bulk running. Like reset or clear etc. /// protected bool IsInternalLoading; - + /// /// ToolBarContent /// protected virtual RenderFragment InternalToolBarContent => null; - + /// /// Is true if the value is a primitive type /// @@ -149,7 +150,7 @@ public T Value /// /// If this setting is true, after import all properties are set instead of full value assignment /// - [Obsolete("This will hopefully be removed in future versions. Only use it if you have problems with the import or restore feature")] + [Obsolete("This will hopefully be removed in future versions. Only use it if you have problems with the import or restore feature")] [Parameter] public bool SetPropertiesAfterImport { get; set; } /// @@ -466,7 +467,7 @@ public bool SearchActive /// The behaviour how registered Meta and configured meta should applied /// [Parameter] public RegisteredConfigurationBehaviour ConfigureBehaviourForRegisteredConfigurations { get; set; } = RegisteredConfigurationBehaviour.ExecutedBefore; - + /** * If this setting is true a manual passed MetaInformation will also re configured */ @@ -476,7 +477,7 @@ public bool SearchActive /// Error message to display /// [Parameter] public string ErrorMessage { get; set; } - + /// /// Set this to handle Reset on your own /// @@ -507,7 +508,7 @@ public bool SearchActive public MudExPropertyEdit Ref { set => Editors.Add(value); } internal static bool IsPrimitive() => MudExObjectEditHelper.HandleAsPrimitive(typeof(T)); - + #region Overrides /// @@ -522,7 +523,7 @@ protected override async Task OnParametersSetAsync() CancelText = TryLocalize("Cancel"), YesText = TryLocalize("Reset") }; - + } /// @@ -709,7 +710,7 @@ protected virtual async Task OnPropertyChange(ObjectEditPropertyMeta property) { if (!IsRendered) return; - + if (AutoSaveRestoreState) _ = Task.Run(SaveState); @@ -746,12 +747,13 @@ private bool IsInFilter(ObjectEditPropertyMeta propertyMeta) // No filters, nothing to filter against, so return true return !allFilters.Any() || // Loop through each filter in allFilters - (from filter in allFilters where !string.IsNullOrWhiteSpace(filter) - select propertyMeta.Settings.LabelFor(LocalizerToUse).Contains(filter, StringComparison.InvariantCultureIgnoreCase) - || propertyMeta.Settings.DescriptionFor(LocalizerToUse).Contains(filter, StringComparison.InvariantCultureIgnoreCase) - || propertyMeta.PropertyInfo.Name.Contains(filter, StringComparison.InvariantCultureIgnoreCase) - || (propertyMeta.Value?.ToString()?.Contains(filter, StringComparison.InvariantCultureIgnoreCase) == true) - || (propertyMeta.GroupInfo?.Name?.Contains(filter, StringComparison.InvariantCultureIgnoreCase) == true) + (from filter in allFilters + where !string.IsNullOrWhiteSpace(filter) + select propertyMeta.Settings.LabelFor(LocalizerToUse).Contains(filter, StringComparison.InvariantCultureIgnoreCase) + || propertyMeta.Settings.DescriptionFor(LocalizerToUse).Contains(filter, StringComparison.InvariantCultureIgnoreCase) + || propertyMeta.PropertyInfo.Name.Contains(filter, StringComparison.InvariantCultureIgnoreCase) + || (propertyMeta.Value?.ToString()?.Contains(filter, StringComparison.InvariantCultureIgnoreCase) == true) + || (propertyMeta.GroupInfo?.Name?.Contains(filter, StringComparison.InvariantCultureIgnoreCase) == true) || (propertyMeta.RenderData?.Attributes.Values.OfType().Any(x => x.Contains(filter, StringComparison.InvariantCultureIgnoreCase)) == true)) .Any(matchesCurrentFilter => matchesCurrentFilter); } @@ -761,7 +763,7 @@ select propertyMeta.Settings.LabelFor(LocalizerToUse).Contains(filter, StringCom private bool ShouldAddGrid(IEnumerable meta) => WrapInMudGrid ?? ContainsMudItemInWrapper(meta); private string CssClassName => GroupingStyle == GroupingStyle.Flat ? $"mud-ex-object-edit-group-flat {(!GroupsCollapsible ? "mud-ex-hide-expand-btn" : "")}" : string.Empty; - + private List> DefaultGroupedMetaPropertyInfos() // Here we filter ignore directly => MetaInformation?.AllProperties?.EmptyIfNull() .Where(m => m.ShouldRender() && IsInFilter(m) && (!AutoHideDisabledFields || m.Settings.IsEditable)) @@ -774,8 +776,8 @@ private List> AllGroupedMetaPropertyIn .GroupBy(m => !DisableGrouping ? m.GroupInfo?.Name : string.Empty) .ToList(); - - private List> GroupedMetaPropertyInfos() + + private List> GroupedMetaPropertyInfos() => !RenderIgnoredReferences ? DefaultGroupedMetaPropertyInfos() : AllGroupedMetaPropertyInfos(); @@ -818,15 +820,15 @@ protected virtual async Task CreateMetaIfNotExists(bool? reconfigure = null) if (c != null) await Task.Run(() => c.Invoke(ConfigureMetaBase(MetaInformation))); else - await Task.Run(() => ConfigureMetaBase(MetaInformation)); - + await Task.Run(() => ConfigureMetaBase(MetaInformation)); + if (ConfigService != null && ConfigureBehaviourForRegisteredConfigurations == RegisteredConfigurationBehaviour.ExecutedAfter) await ConfigService.ConfigureAsync(MetaInformation); - - UpdateConditions(); + + UpdateConditions(); } } - + private async Task OnResetClick(MouseEventArgs arg) { if (GlobalResetSettings.RequiresConfirmation && DialogService != null && !(await ShowConfirmationBox())) @@ -834,7 +836,7 @@ private async Task OnResetClick(MouseEventArgs arg) await Reset(); CallStateHasChanged(); } - + private async Task ShowConfirmationBox() { ResetConfirmationDialogOptions ??= new DialogOptionsEx @@ -936,18 +938,18 @@ private IDictionary GetAttributesForPrimitive() return res; } - + private IDictionary GetCompatibleParameters(Type componentType) { var res = ComponentRenderHelper.GetCompatibleParameters(this, componentType) .Where(p => IsOverwritten(p.Key)).ToDictionary(p => p.Key, p => p.Value); - + foreach (var parameter in UserAttributes.Where(parameter => ComponentRenderHelper.IsValidParameter(componentType, parameter.Key, parameter.Value))) { res.AddOrUpdate(parameter.Key, parameter.Value); } - if(ReadOnlyOverwrite.HasValue) + if (ReadOnlyOverwrite.HasValue) res.AddOrUpdate(nameof(MudBaseInput.ReadOnly), ReadOnlyOverwrite.Value); res.AddOrUpdate(nameof(Value), Value); res.AddOrUpdate(nameof(ValueChanged), RuntimeHelpers.TypeCheck( @@ -974,8 +976,8 @@ protected async Task Export() { var exported = new ExportData { Value = Value, Json = await ToJsonAsync() }; await BeforeExport.InvokeAsync(exported); - - if(exported.Cancel) + + if (exported.Cancel) return; IsInternalLoading = true; @@ -1012,7 +1014,7 @@ public Task ToJsonAsync() public string ToJson() { var ignored = MetaInformation.Properties().Where(p => p.Settings.IgnoreOnExport).Select(m => m.PropertyName).ToArray(); - + var json = JsonConvert.SerializeObject(Value, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore, @@ -1067,7 +1069,7 @@ private async Task Import(InputFileChangeEventArgs e) { var buffer = new byte[e.File.Size]; await e.File.OpenReadStream(e.File.Size).ReadAsync(buffer); - + var toImport = new ImportData { Json = Encoding.UTF8.GetString(buffer), Value = Value }; await BeforeImport.InvokeAsync(toImport); if (toImport.Cancel || await ShouldCancelImportAsync(toImport.Json, e.File.Name)) @@ -1078,7 +1080,7 @@ private async Task Import(InputFileChangeEventArgs e) await LoadFromJson(toImport.Json, RemoveIgnoredFromImport); await ImportSuccessUi(); - await AfterImport.InvokeAsync(new ImportedData {Json = toImport.Json, Value = Value}); + await AfterImport.InvokeAsync(new ImportedData { Json = toImport.Json, Value = Value }); } catch (Exception ex) { @@ -1117,7 +1119,7 @@ public Task LoadFromJson(string json, bool removeIgnoredImports) SetValueAfterImport(JsonConvert.DeserializeObject(json)); return; } - + var obj = JsonConvert.DeserializeObject(json, Value.GetType()); var notIgnored = obj.ToFlatDictionary().Where(kvp => !ignored.Contains(kvp.Key) && !ignored.Any(path => PropertyHelper.IsPropertyPathSubPropertyOf(kvp.Key, path))).ToDictionary(kvp => kvp.Key, kvp => kvp.Value); @@ -1134,7 +1136,7 @@ public Task LoadFromJson(string json, bool removeIgnoredImports) } private void SetValueAfterImport(T value) { - if(SetPropertiesAfterImport) + if (SetPropertiesAfterImport) SetEditorValueProperties(value); else Value = value; @@ -1177,4 +1179,17 @@ private IDictionary GetPropertiesWithPaths(object obj, string cu return result; } + + bool _defaultFocus = true; + private bool HasAutoFocus(ObjectEditPropertyMeta property) + { + var isConfigured = MetaInformation.AllProperties.Any(p => p?.Settings?.AutoFocus == true); + if (isConfigured) + return property?.Settings?.AutoFocus == true; + var res = _defaultFocus; + _defaultFocus = false; + if (res) + property.WithDefaultFocus(); + return res; + } } \ No newline at end of file diff --git a/MudBlazor.Extensions/Components/ObjectEdit/MudExObjectEditDialog.razor.cs b/MudBlazor.Extensions/Components/ObjectEdit/MudExObjectEditDialog.razor.cs index e5b19960..d51243c1 100644 --- a/MudBlazor.Extensions/Components/ObjectEdit/MudExObjectEditDialog.razor.cs +++ b/MudBlazor.Extensions/Components/ObjectEdit/MudExObjectEditDialog.razor.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Forms; +using Microsoft.JSInterop; using MudBlazor.Extensions.Components.ObjectEdit.Options; using MudBlazor.Extensions.Core; using MudBlazor.Extensions.Helper; @@ -129,7 +130,7 @@ protected override async Task OnSubmit(EditContext ctx) await base.OnSubmit(ctx); if (CustomSubmit == null || string.IsNullOrWhiteSpace(_errorMessage = await CustomSubmit.Invoke(Value, this))) { - MudDialog.CloseAnimatedIf(DialogResult.Ok(Value)); + MudDialog.CloseAnimatedIf(DialogResult.Ok(Value), JsRuntime); } } finally @@ -145,6 +146,6 @@ protected override async Task OnSubmit(EditContext ctx) protected override async Task Cancel() { await base.Cancel(); - MudDialog.CancelAnimatedIf(); + MudDialog.CancelAnimatedIf(JsRuntime); } } \ No newline at end of file diff --git a/MudBlazor.Extensions/Components/ObjectEdit/MudExObjectEditExtensions.PropertyMeta.cs b/MudBlazor.Extensions/Components/ObjectEdit/MudExObjectEditExtensions.PropertyMeta.cs index 4b5abf87..b042c9ac 100644 --- a/MudBlazor.Extensions/Components/ObjectEdit/MudExObjectEditExtensions.PropertyMeta.cs +++ b/MudBlazor.Extensions/Components/ObjectEdit/MudExObjectEditExtensions.PropertyMeta.cs @@ -235,6 +235,15 @@ public static ObjectEditPropertyMeta RenderWith(this ObjectEditPropertyMeta meta public static ObjectEditPropertyMeta AsReadOnly(this ObjectEditPropertyMeta meta, bool isReadOnly = true) => meta?.SetProperties(p => p.Settings.IsEditable = !isReadOnly, p => p?.RenderData?.AddAttributes(true, new KeyValuePair(nameof(MudBaseInput.ReadOnly), isReadOnly))); + /// + /// Marks an ObjectEditPropertyMeta to have Auto focus + /// The ObjectEditPropertyMeta instance to modify. + /// The modified ObjectEditPropertyMeta instance. + /// + public static ObjectEditPropertyMeta WithDefaultFocus(this ObjectEditPropertyMeta meta) + => meta?.SetProperties(p => p.Settings.AutoFocus = true, p => p?.RenderData?.AddAttributes(true, new KeyValuePair(nameof(MudBaseInput.AutoFocus), true))); + + /// /// Disables the underline for an ObjectEditPropertyMeta. /// The ObjectEditPropertyMeta instance to modify. diff --git a/MudBlazor.Extensions/Components/ObjectEdit/MudExPropertyEdit.razor b/MudBlazor.Extensions/Components/ObjectEdit/MudExPropertyEdit.razor index a0f38f83..f90ac231 100644 --- a/MudBlazor.Extensions/Components/ObjectEdit/MudExPropertyEdit.razor +++ b/MudBlazor.Extensions/Components/ObjectEdit/MudExPropertyEdit.razor @@ -77,6 +77,7 @@ //Todo we need to have value changed or something to raise also this PropertyValueChanged result = @ diff --git a/MudBlazor.Extensions/Components/ObjectEdit/MudExPropertyEdit.razor.cs b/MudBlazor.Extensions/Components/ObjectEdit/MudExPropertyEdit.razor.cs index 983f41fb..06a31743 100644 --- a/MudBlazor.Extensions/Components/ObjectEdit/MudExPropertyEdit.razor.cs +++ b/MudBlazor.Extensions/Components/ObjectEdit/MudExPropertyEdit.razor.cs @@ -16,6 +16,17 @@ namespace MudBlazor.Extensions.Components.ObjectEdit; /// public partial class MudExPropertyEdit { + private bool? _autoFocus; + + /// + /// Editor should be focused on load + /// + [Parameter] + public bool AutoFocus + { + get => _autoFocus ?? PropertyMeta.Settings.AutoFocus; + set => _autoFocus = value; + } /// /// If this is set all properties will be readonly depending on the value otherwise the property settings for meta configuration will be used @@ -87,6 +98,7 @@ public DynamicComponent Editor private bool _urlSetDone; private DynamicComponent _editor; + //private Expression> CreateFieldForExpression() // => Check.TryCatch>, Exception>(() => Expression.Lambda>(Expression.Property(Expression.Constant(PropertyMeta.ReferenceHolder, PropertyMeta.ReferenceHolder.GetType()), PropertyMeta.PropertyInfo))); @@ -159,6 +171,7 @@ private IDictionary GetPreparedAttributes() .TrySetAttributeIfAllowed(nameof(Style), () => Style) .TrySetAttributeIfAllowed(nameof(Localizer), Localizer) .TrySetAttributeIfAllowed(nameof(RenderKey), RenderKey) + .TrySetAttributeIfAllowed(nameof(AutoFocus), AutoFocus) .TrySetAttributeIfAllowed(nameof(MudBaseInput.ReadOnly), () => !PropertyMeta.Settings.IsEditable); if (ReadOnlyOverwrite.HasValue) diff --git a/MudBlazor.Extensions/Components/ObjectEdit/Options/ObjectEditPropertyMetaSettings.cs b/MudBlazor.Extensions/Components/ObjectEdit/Options/ObjectEditPropertyMetaSettings.cs index 3d342de8..bc7fd364 100644 --- a/MudBlazor.Extensions/Components/ObjectEdit/Options/ObjectEditPropertyMetaSettings.cs +++ b/MudBlazor.Extensions/Components/ObjectEdit/Options/ObjectEditPropertyMetaSettings.cs @@ -47,7 +47,12 @@ public ObjectEditPropertyMetaSettings(ObjectEditPropertyMeta owner) /// Determines if the property is editable. /// public bool IsEditable { get; set; } - + + /// + /// Should have Auto focus. + /// + public bool AutoFocus { get; set; } + /// /// Determines if the property is ignored. /// diff --git a/MudBlazor.Extensions/Docs/CHANGELOG.md b/MudBlazor.Extensions/Docs/CHANGELOG.md index e2f4766b..4747e725 100644 --- a/MudBlazor.Extensions/Docs/CHANGELOG.md +++ b/MudBlazor.Extensions/Docs/CHANGELOG.md @@ -1,4 +1,8 @@ ## Change Log + - 2.1.0 > MudExObject now supports default focused element within the meta configuration with `meta.Property(m => m.LastName).WithDefaultFocus()` + - 2.1.0 > MudExObject edit now has AutoFocus for first input field if no other focus is configured + - 2.1.0 > Provide a Middleware again without deprecated UseMudExtensions now you should use `app.Use(MudExWebApp.MudExMiddleware);` + - 2.1.0 > Fix another bug with dialog that only occurs on webassembly projects hosted in a .net8 runtime - 2.0.9 > Fix bug with dialog animations on server side rendered projects #112 - 2.0.8 > Ensure dialog initial relative state if configured - 2.0.8 > Fix Remove Item Bug in Collection editor diff --git a/MudBlazor.Extensions/Helper/MudDialogInstanceExtensions.cs b/MudBlazor.Extensions/Helper/MudDialogInstanceExtensions.cs index c8d34faa..c7fe41d4 100644 --- a/MudBlazor.Extensions/Helper/MudDialogInstanceExtensions.cs +++ b/MudBlazor.Extensions/Helper/MudDialogInstanceExtensions.cs @@ -29,9 +29,16 @@ public static void CloseAnimatedIf(this MudDialogInstance instance, T result, private static async Task AnimateClose(this MudDialogInstance instance, Func callback, IJSRuntime jsRuntime = null, bool checkOptions = false) { - var dialogId = DialogReferenceExtensions.PrepareDialogId(instance.Id); - await (jsRuntime ?? JsImportHelper.GetInitializedJsRuntime()).InvokeVoidAsync("MudBlazorExtensions.closeDialogAnimated", dialogId, checkOptions); - await callback(instance); + try + { + var dialogId = DialogReferenceExtensions.PrepareDialogId(instance.Id); + await (jsRuntime ?? JsImportHelper.GetInitializedJsRuntime()).InvokeVoidAsync("MudBlazorExtensions.closeDialogAnimated", dialogId, checkOptions); + } + finally + { + await callback(instance); + } + } } diff --git a/MudBlazor.Extensions/Middleware/MudBlazorExtensionsMiddleware.cs b/MudBlazor.Extensions/Middleware/MudBlazorExtensionsMiddleware.cs deleted file mode 100644 index 0b161bef..00000000 --- a/MudBlazor.Extensions/Middleware/MudBlazorExtensionsMiddleware.cs +++ /dev/null @@ -1,33 +0,0 @@ -//using Microsoft.AspNetCore.Http; -//using Microsoft.JSInterop; -//using MudBlazor.Extensions.Helper; - -//namespace MudBlazor.Extensions.Middleware; - -///// -///// Middleware for MudBlazor extensions that allows to inject IJSRuntime. -///// -//public class MudBlazorExtensionsMiddleware -//{ -// private readonly RequestDelegate _next; - -// /// -// /// Initializes a new instance of the class. -// /// -// /// The next middleware in the pipeline. -// public MudBlazorExtensionsMiddleware(RequestDelegate next) -// { -// _next = next; -// } - -// /// -// /// Method invoked by the pipeline. Injects IJSRuntime into JsImportHelper and then passes control to the next middleware in the pipeline. -// /// -// /// The HttpContext for the current request. -// /// The IJSRuntime instance for the current request. -// public async Task InvokeAsync(HttpContext context, IJSRuntime jsRuntime) -// { -// JsImportHelper.LegacyRuntimeReference = jsRuntime; -// await _next(context); -// } -//} diff --git a/MudBlazor.Extensions/MudBlazor.Extensions.csproj b/MudBlazor.Extensions/MudBlazor.Extensions.csproj index 29b30378..bb6d2357 100644 --- a/MudBlazor.Extensions/MudBlazor.Extensions.csproj +++ b/MudBlazor.Extensions/MudBlazor.Extensions.csproj @@ -68,6 +68,7 @@ + diff --git a/MudBlazor.Extensions/MudBlazorExtensionsMiddlewareExtensions.cs b/MudBlazor.Extensions/MudBlazorExtensionsMiddlewareExtensions.cs deleted file mode 100644 index bb4c5935..00000000 --- a/MudBlazor.Extensions/MudBlazorExtensionsMiddlewareExtensions.cs +++ /dev/null @@ -1,20 +0,0 @@ -//using Microsoft.AspNetCore.Builder; -//using MudBlazor.Extensions.Middleware; - -//namespace MudBlazor.Extensions; - -///// -///// MudBlazorExtensionsMiddlewareExtensions -///// -//public static class MudBlazorExtensionsMiddlewareExtensions -//{ -// /// -// /// Adds the MudBlazorExtensionsMiddleware -// /// -// /// -// /// -// public static IApplicationBuilder UseMudExtensions(this IApplicationBuilder builder) -// { -// return builder.UseMiddleware(); -// } -//} \ No newline at end of file diff --git a/MudBlazor.Extensions/MudExWebApp.cs b/MudBlazor.Extensions/MudExWebApp.cs new file mode 100644 index 00000000..90e72c1e --- /dev/null +++ b/MudBlazor.Extensions/MudExWebApp.cs @@ -0,0 +1,45 @@ +using Microsoft.Extensions.Hosting; +using Microsoft.JSInterop; +using MudBlazor.Extensions.Helper; +using System.Net.Http; +using Microsoft.Extensions.DependencyInjection; + +namespace MudBlazor.Extensions; + +/// +/// MudBlazorExtensionsMiddlewareExtensions +/// +public static class MudExWebApp +{ + + //public static IApplicationBuilder UseMudExtensions(this IApplicationBuilder builder) + //{ + + // return builder.Use(async (context, next) => + // { + // var jsRuntime = context.RequestServices.GetRequiredService(); + // JsImportHelper.LegacyRuntimeReference = jsRuntime; + // await next(); + // }); + //} + + //public static WebApplication UseMudExtensions(this WebApplication app) + //{ + // app.Use(async (context, next) => + // { + // var jsRuntime = context.RequestServices.GetRequiredService(); + // JsImportHelper.LegacyRuntimeReference = jsRuntime; + // await next(context); + // }); + // return app; + //} + + public static Func, Task> MudExMiddleware => + async (context, next) => + { + var p = context?.GetType()?.GetProperty("RequestServices")?.GetValue(context) as IServiceProvider; + var jsRuntime = p?.GetRequiredService(); + JsImportHelper.LegacyRuntimeReference = jsRuntime; + await next(); + }; +} \ No newline at end of file diff --git a/MudBlazor.Extensions/wwwroot/docs/MudBlazor.Extensions.xml b/MudBlazor.Extensions/wwwroot/docs/MudBlazor.Extensions.xml index 50efdcc7..e874d70a 100644 --- a/MudBlazor.Extensions/wwwroot/docs/MudBlazor.Extensions.xml +++ b/MudBlazor.Extensions/wwwroot/docs/MudBlazor.Extensions.xml @@ -10643,6 +10643,13 @@ The modified ObjectEditPropertyMeta instance. + + + Marks an ObjectEditPropertyMeta to have Auto focus + The ObjectEditPropertyMeta instance to modify. + The modified ObjectEditPropertyMeta instance. + + Disables the underline for an ObjectEditPropertyMeta. @@ -13225,6 +13232,11 @@ Editor for a property of an object. Used internally inside the MudExObjectEdit + + + Editor should be focused on load + + If this is set all properties will be readonly depending on the value otherwise the property settings for meta configuration will be used @@ -13663,6 +13675,11 @@ Determines if the property is editable. + + + Should have Auto focus. + + Determines if the property is ignored. @@ -21884,6 +21901,11 @@ The position of the button. A string containing the generated HTML. + + + MudBlazorExtensionsMiddlewareExtensions + + Represents the animation timing function. diff --git a/README.md b/README.md index a068ada5..7b8c75ad 100644 --- a/README.md +++ b/README.md @@ -90,8 +90,8 @@ builder.Services.AddMudServicesWithExtensions(c => if your are running on Blazor Server side, you should also use the `MudBlazorExtensionMiddleware` you can do this in your startup or program.cs by adding the following line on your WebApplication: -``` - app.UseMudExtensions(); +``` + app.Use(MudExWebApp.MudExMiddleware); ``` (Optional) if you have problems with automatic loaded styles you can also load the styles manually by adding the following line to your `index.html` or `_Host.cshtml` @@ -389,6 +389,10 @@ MudBlazor.Extensions is released under the MIT License. See the bundled LICENSE Latest Changes: + - 2.1.0 > MudExObject now supports default focused element within the meta configuration with `meta.Property(m => m.LastName).WithDefaultFocus()` + - 2.1.0 > MudExObject edit now has AutoFocus for first input field if no other focus is configured + - 2.1.0 > Provide a Middleware again without deprecated UseMudExtensions now you should use `app.Use(MudExWebApp.MudExMiddleware);` + - 2.1.0 > Fix another bug with dialog that only occurs on webassembly projects hosted in a .net8 runtime - 2.0.9 > Fix bug with dialog animations on server side rendered projects #112 - 2.0.8 > Ensure dialog initial relative state if configured - 2.0.8 > Fix Remove Item Bug in Collection editor diff --git a/Samples/MainSample.ServerSide/Pages/_Host.cshtml b/Samples/MainSample.ServerSide/Pages/_Host.cshtml index 6c5f1405..7fe9e63a 100644 --- a/Samples/MainSample.ServerSide/Pages/_Host.cshtml +++ b/Samples/MainSample.ServerSide/Pages/_Host.cshtml @@ -30,7 +30,7 @@ - + diff --git a/Samples/MainSample.ServerSide/Program.cs b/Samples/MainSample.ServerSide/Program.cs index 66996147..2e4a2bdb 100644 --- a/Samples/MainSample.ServerSide/Program.cs +++ b/Samples/MainSample.ServerSide/Program.cs @@ -1,7 +1,9 @@ using MainSample.WebAssembly; using MainSample.WebAssembly.ObjectEditMetaConfig; +using Microsoft.JSInterop; using MudBlazor; using MudBlazor.Extensions; +using MudBlazor.Extensions.Helper; var builder = WebApplication.CreateBuilder(args); @@ -36,6 +38,7 @@ app.MapBlazorHub(); app.MapFallbackToPage("/_Host"); -//app.UseMudExtensions(); +app.Use(MudExWebApp.MudExMiddleware); + app.Run(); diff --git a/Samples/MainSample.WebAssembly/Pages/Page_ObjectEditConfigured.razor b/Samples/MainSample.WebAssembly/Pages/Page_ObjectEditConfigured.razor index e40de7ef..de414246 100644 --- a/Samples/MainSample.WebAssembly/Pages/Page_ObjectEditConfigured.razor +++ b/Samples/MainSample.WebAssembly/Pages/Page_ObjectEditConfigured.razor @@ -82,7 +82,10 @@ {nameof(MudSelect.Variant), Variant.Filled} }); - meta.Property(m => m.LastName).WithLabel("Surname").WithAdditionalAttributes>( + meta.Property(m => m.LastName) + .WithLabel("Surname") + .WithDefaultFocus() + .WithAdditionalAttributes>( t => t.AdornmentIcon = Icons.Material.Outlined.Abc, t => t.Adornment = Adornment.End, t => t.Immediate = true, diff --git a/Samples/MainSample.WebAssembly/Pages/Page_StructuredDataEdit.razor b/Samples/MainSample.WebAssembly/Pages/Page_StructuredDataEdit.razor index aab5d5b9..9c1e87a0 100644 --- a/Samples/MainSample.WebAssembly/Pages/Page_StructuredDataEdit.razor +++ b/Samples/MainSample.WebAssembly/Pages/Page_StructuredDataEdit.razor @@ -76,7 +76,12 @@ private async Task OnSaveClick(EditContext arg) => await JsRuntime.AlertAsync(arg.Model.ToString()); - private async Task OnDataStringChanged(string arg) => await _editor.SetValue(_dataString = arg); + private async Task OnDataStringChanged(string arg) + { + if (_editor == null) + return; + await _editor.SetValue(_dataString = arg); + } private async Task ResetDataString() { diff --git a/Samples/MainSample.WebAssembly/Shared/ProgrammingSkillSelect.razor b/Samples/MainSample.WebAssembly/Shared/ProgrammingSkillSelect.razor index 9f3d9012..7b4d4195 100644 --- a/Samples/MainSample.WebAssembly/Shared/ProgrammingSkillSelect.razor +++ b/Samples/MainSample.WebAssembly/Shared/ProgrammingSkillSelect.razor @@ -28,5 +28,5 @@ }); } - private static string ItemNameRenderFn(Page_ObjectEditConfigured.ProgramingSkill item) => $"{item.Name}"; + private static string ItemNameRenderFn(Page_ObjectEditConfigured.ProgramingSkill item) => $"{item?.Name}"; } \ No newline at end of file