radzenhq / radzen-blazor

Radzen Blazor is a set of 90+ free native Blazor UI components packed with DataGrid, Scheduler, Charts and robust theming including Material design and FluentUI.
https://www.radzen.com
MIT License
3.52k stars 785 forks source link

[BUG] RadzenDataFilter does not produce expected LogicalFilterOperator via Filters property #1685

Closed kerajel closed 1 month ago

kerajel commented 1 month ago

Single-page set up

@using System.Text.Json

<RadzenDataFilter @ref="compositeFilter" Auto="false" Style="width: 50%;" TItem="DebugSampleComposite">
    <Properties>
        <RadzenDataFilterProperty Property="Sample.Longtitute" Title="Longtitute" />
        <RadzenDataFilterProperty Property="Sample.Latitude" Title="Latitude" />
    </Properties>
</RadzenDataFilter>

<RadzenButton Text="Click composite" Click="OnClickComposite" />

<p/>

<RadzenDataFilter @ref="simpleFilter" Auto="false" Style="width: 50%;" TItem="DebugSample">
    <Properties>
        <RadzenDataFilterProperty Property="Longtitute" Title="Longtitute" />
        <RadzenDataFilterProperty Property="Latitude" Title="Latitude" />
    </Properties>
</RadzenDataFilter>

<RadzenButton Text="Click simple" Click="OnClickSimple" />

@code {

    private RadzenDataFilter<DebugSampleComposite> compositeFilter = null!;
    private RadzenDataFilter<DebugSample> simpleFilter = null!;

    void OnClickComposite()
    {
        CompositeFilterDescriptor[] descriptors = compositeFilter.Filters.ToArray();
        string serializedDescriptors = JsonSerializer.Serialize(descriptors);
        string linqFilter = compositeFilter.ToFilterString();
        Console.WriteLine(serializedDescriptors);
        Console.WriteLine(linqFilter);
    }

    void OnClickSimple()
    {
        CompositeFilterDescriptor[] descriptors = simpleFilter.Filters.ToArray();
        string serializedDescriptors = JsonSerializer.Serialize(descriptors);
        string linqFilter = simpleFilter.ToFilterString();
        Console.WriteLine(serializedDescriptors);
        Console.WriteLine(linqFilter);
    }

    public class DebugSampleComposite
    {
        public DebugSample Sample { get; set; } = null!;
    }

    public class DebugSample
    {
        public decimal Longtitute { get; set; }

        public decimal Latitude { get; set; }
    }
}

Reproduced on both complex and flat objects

Wire up the page, set values for both filters as on the screenshot image

Notice usage of the 'Or' operator

Click both buttons, observe correct value from ToFilterString() and incorrect value from Filters

Click Composite

[
    {
        "Property": "Sample.Longtitute",
        "FilterValue": 1,
        "FilterOperator": 0,
        "LogicalFilterOperator": 0, // expected 1
        "Filters": null
    },
    {
        "Property": "Sample.Latitude",
        "FilterValue": 2,
        "FilterOperator": 0,
        "LogicalFilterOperator": 0, // expected 1
        "Filters": null
    }
]
// This generates the filter string: (Sample.Longtitute = 1) || (Sample.Latitude = 2)

Click Simple

[
    {
        "Property": "Longtitute",
        "FilterValue": 1,
        "FilterOperator": 0,
        "LogicalFilterOperator": 0, // expected 1
        "Filters": null
    },
    {
        "Property": "Longtitute",
        "FilterValue": 2,
        "FilterOperator": 0,
        "LogicalFilterOperator": 0, // expected 1
        "Filters": null
    }
]
// This generates the filter string: Longtitute = 1 || Longtitute = 2

Expected behavior LogicalFilterOperator is set to 1 ('Or') for CompositeFilterDescriptors (Filters)

_Radzen.Blazor Version="5.1.9"

enchev commented 1 month ago

The LogicalFilterOperator that you are looking at is for the inner filters of the CompositeFilterDescriptor, the one you should look at is defined at the DataFilter level: image