Power-Components / livewire-powergrid

⚡ PowerGrid generates modern, powerful and easy-to-customize data tables using Laravel Livewire.
https://livewire-powergrid.com
MIT License
1.41k stars 205 forks source link

Clearing filter with a dot (.) clears too much #1496

Closed edwinheij closed 2 months ago

edwinheij commented 3 months ago

Have you searched through other issues to see if your problem is already reported or has been fixed?

Yes, I did not find it.

Did you read the documentation?

Yes, I did not find it.

Have you tried to publish the views?

Yes - I didn't work.

Is there an error in the console?

No

PHP Version

8.2.16

PowerGrid

5.4.9

Laravel

10.39.0

Livewire

3.4.10

Alpine JS

No response

Theme

Tailwind 3.x

Describe the bug.

When clearing a filter from a relation (with a dot (.)) too much filters are cleared. All the fields from a specific type of that relation are cleared. A Filter::select(...) for relation.actual and relation.actual2 are both cleared when only clearing relation.actual from the UI.

To Reproduce...

To reproduce I make a repo for it: https://github.com/edwinheij/livewire-powergrid-fail You can see the 'normal' actual filters are fine, but relation.actual and relation.actual2 fields can't be cleared the way you would expect.

Extra information

A quick workaround/fix would be in /Concerns/Filter.php (didn't fully test it, you can do better I guess)

Change (line 36):

$unset = function ($filter, $field, $column) {
    $key = data_get($filter, 'key');

    if (str($field)->contains('.')) {
        $explodeField = explode('.', $field);

        $currentArray = &$this->filters[$key];
        unset($currentArray[$explodeField[0]]);
    }

    unset($this->filters[$key][$field]);

    $this->enabledFilters = array_filter(
        $this->enabledFilters,
        fn ($filter) => $filter['field'] !== ($column ?? $field)
    );
};

to:

$unset = function ($filter, $field, $column) {
    $key = data_get($filter, 'key');

    if (str($field)->contains('.')) {
        $explodeField = explode('.', $field);

        $currentArray = &$this->filters[$key];
        unset($currentArray[$explodeField[0]][$explodeField[1]]);

        if (empty($currentArray[$explodeField[0]])) {
            unset($currentArray[$explodeField[0]]);
        }
    }

    unset($this->filters[$key][$field]);

    $this->enabledFilters = array_filter(
        $this->enabledFilters,
        fn ($filter) => $filter['field'] !== ($column ?? $field)
    );
};
luanfreitasdev commented 2 months ago

I think this works well. Could you send a PR?

Thank you