< Summary

Information
Class: Nabs.Ui.Forms.DynamicForm<T>
Assembly: Nabs.Ui
File(s): /home/runner/work/Nabs/Nabs/src/Nabs.Ui/Forms/DynamicForm.razor
Tag: 90_14636759620
Line coverage
92%
Covered lines: 81
Uncovered lines: 7
Coverable lines: 88
Total lines: 143
Line coverage: 92%
Branch coverage
66%
Covered branches: 12
Total branches: 18
Branch coverage: 66.6%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
BuildRenderTree(...)100%22100%
RenderBlazorUiGroup(...)100%11100%
RenderBlazorUiHint(...)100%44100%
CreateInputComponent(...)100%11100%
CreateEventCallback(...)40%181056.25%
SetValueChangedArgs(...)100%11100%

File(s)

/home/runner/work/Nabs/Nabs/src/Nabs.Ui/Forms/DynamicForm.razor

#LineLine coverage
 1@using System.Linq.Expressions
 2@inject BlazorUiMappings _blazorUiMappings
 3@typeparam TModel
 4
 15@if (Model is not null)
 6{
 7    <EditForm Model="@Model">
 8        <Header />
 39        @foreach (var property in typeof(TModel).GetProperties())
 10        {
 11            @RenderBlazorUiGroup(property)
 12            @RenderBlazorUiHint(property, Model)
 13        }
 14        <br />
 15        <button type="submit" class="btn btn-primary">Submit</button>
 16        @ChildContent
 17        <Footer />
 18    </EditForm>
 19}
 20
 21@code {
 22    [Parameter]
 23    public TModel? Model { get; set; }
 24
 25    [Parameter]
 26    public RenderFragment? ChildContent { get; set; }
 27
 128    private RenderFragment RenderBlazorUiGroup(PropertyInfo propertyInfo) => builder =>
 129    {
 130        var uiGroup = propertyInfo.GetCustomAttribute<BlazorUIGroupAttribute>();
 131        if (uiGroup is null)
 132        {
 133            return;
 134        }
 135
 136        // var propertyType = propertyInfo.PropertyType;
 137        // var value = propertyInfo.GetValue(Model);
 138
 139        // var formGroupWrapper = BlazorUiMappings.FormGroupWrapper!;
 140
 141        // builder.OpenComponent(1, formGroupWrapper);
 142        // builder.AddAttribute(1, "Title", uiGroup.UiTitle);
 143        // foreach (var childProperty in propertyInfo.PropertyType.GetProperties())
 144        // {
 145        //     builder.AddAttribute(2, "ChildContent", (RenderFragment)(childBuilder =>
 146        //     {
 147        //         RenderBlazorUiHint(childProperty, value)(childBuilder);
 148        //     }));
 149        // }
 150        // builder.CloseComponent();
 151    };
 52
 153    private RenderFragment RenderBlazorUiHint<T>(PropertyInfo propertyInfo, T model) => builder =>
 154    {
 155        var uiHint = propertyInfo.GetCustomAttribute<BlazorUIHintAttribute>();
 156        if (uiHint is null)
 157        {
 158            return;
 159        }
 160
 161        var inputSequence = 0;
 162        var wrapperSequence = 0;
 163
 164        var propertyType = propertyInfo.PropertyType;
 165        var value = propertyInfo.GetValue(model);
 166
 167        var formInputWrapper = _blazorUiMappings.FormInputWrapper;
 168        if (formInputWrapper != null)
 169        {
 170            builder.OpenComponent(wrapperSequence++, formInputWrapper);
 171            builder.AddAttribute(1, "Id", propertyInfo.Name);
 172            builder.AddAttribute(2, "Label", uiHint.UiLabel);
 173            builder.AddAttribute(3, "ChildContent", (RenderFragment)(childBuilder =>
 174            {
 175                CreateInputComponent(childBuilder, uiHint, inputSequence, propertyInfo, value);
 176                childBuilder.CloseComponent();
 277            }));
 178        }
 179        else
 180        {
 181            CreateInputComponent(builder, uiHint, inputSequence, propertyInfo, value);
 182        }
 183
 184        builder.CloseComponent();
 285    };
 86
 87    private void CreateInputComponent(RenderTreeBuilder builder, BlazorUIHintAttribute uiHint,
 88        int inputSequence, PropertyInfo propertyInfo, object? value)
 89    {
 190        var attributeSequence = 0;
 191        var componentType = _blazorUiMappings.InputMappings[uiHint.UIComponent];
 192        builder.OpenComponent(inputSequence++, componentType);
 193        builder.AddAttribute(attributeSequence++, "Id", propertyInfo.Name);
 194        builder.AddAttribute(attributeSequence++, "Label", uiHint.UiLabel);
 195        builder.AddAttribute(attributeSequence++, "Value", value);
 196        CreateEventCallback(builder, propertyInfo, value);
 197    }
 98
 99    private void CreateEventCallback(RenderTreeBuilder builder, PropertyInfo propertyInfo, object? value)
 100    {
 1101        var underlyingType = Nullable.GetUnderlyingType(propertyInfo.PropertyType);
 102
 1103        (RenderTreeBuilder builder, int sequence, PropertyInfo propertyInfo) valueChangedArgs =
 1104            (builder, 4, propertyInfo);
 105
 1106        var typeCode = Type.GetTypeCode(propertyInfo.PropertyType);
 1107        switch (typeCode)
 108        {
 109            case TypeCode.Int32:
 1110                SetValueChangedArgs<int>(valueChangedArgs);
 1111                break;
 112
 113            case TypeCode.String:
 1114                SetValueChangedArgs<string>(valueChangedArgs);
 1115                break;
 116
 0117            case TypeCode.Object when propertyInfo.PropertyType == typeof(DateOnly):
 0118                SetValueChangedArgs<DateOnly>(valueChangedArgs);
 0119                break;
 120
 0121            case TypeCode.Object when propertyInfo.PropertyType == typeof(int?):
 0122                SetValueChangedArgs<int?>(valueChangedArgs);
 0123                break;
 124
 125            // case TypeCode.Object when propertyInfo.PropertyType == typeof(int?):
 126            //     SetValueChangedArgs<int?>(valueChangedArgs);
 127            //     break;
 128
 129            default:
 0130                return;
 131        }
 132    }
 133
 134    private void SetValueChangedArgs<T>((RenderTreeBuilder builder, int sequence, PropertyInfo propertyInfo) args)
 135    {
 1136        args.builder.AddAttribute(args.sequence++, "ValueChanged",
 2137            EventCallback.Factory.Create(this, (T val) => args.propertyInfo.SetValue(Model, val)));
 138
 1139        args.builder.AddAttribute(args.sequence, "ValueExpression", Expression.Lambda<Func<T>>(Expression.Property(
 1140            Expression.Constant(Model), args.propertyInfo)));
 1141    }
 142
 143}