Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow defaultSort to accept Livewire #12687

Merged

Conversation

archilex
Copy link
Contributor

@archilex archilex commented May 8, 2024

Description

This PR allows defaultSort() to accept Livewire as a closure.

return $table
     ->defaultSort(function (Component $livewire) {
          return $livewire->activeTab === 'inStock' ? 'qty' : 'created_at';
     })

Of course passing in Builder or a string continues to work as well.

Note: my first attempt was to keep the original condition and then evaluate the closure inside getDefaultSortQuery(), however applyDefaultSortingToTableQuery() calls getDefaultSortColumn() before getDefaultSortQuery() so we have to evaluate there. This turned out to be cleaner anyway.

  • Code style has been fixed by running the composer cs command.
  • Changes have been tested to not break existing functionality.
  • Documentation is up-to-date.

@zepfietje zepfietje added the enhancement New feature or request label May 8, 2024
@zepfietje zepfietje added this to the v3 milestone May 8, 2024
@danharrin
Copy link
Member

Is there a way to refactor defaultSortColumn and defaultSortQuery into a single defaultSort property? Because I don't think they should both be set at the same time, right? And it feels really weird to set one property from the getter of the other.

@archilex
Copy link
Contributor Author

archilex commented May 15, 2024

Hi Dan, I refactored this to a single defaultSort property as requested. I tested with each possible way this could be configured and everything worked as expected (string, closure, builder). And the methods I removed aren't used anywhere else so we should be good to go.

I guess if there were any app/plugins that tapping into one of these methods (cough cough AdvancedTables), this would be a breaking change...not sure how you want to handle that.

Finally, I did notice that inside

if ($defaultSort instanceof Closure) {
    app()->call($defaultSort, [
        'direction' => $sortDirection,
        'query' => $query,
    ]);

    return $query;
}

the direction parameter has no affect at all. This doesn't appear to be because of this PR as I couldn't get this to work in the current release either. In other words:

->defaultSort(fn (Builder $query) => $query->orderBy('status'), 'desc')

doesn't sort the table by desc. For that to work you apply it directly to the query:

->defaultSort(fn (Builder $query) => $query->orderBy('status', 'desc'))

Just wanted you to know.

@danharrin
Copy link
Member

doesn't sort the table by desc. For that to work you apply it directly to the query:

It is only useful when using a string column, not a query function. If you pass a column name, it does apply. If you pass a query function, you need to accept $direction as a param of the function and pass it to your orderBy()

@archilex
Copy link
Contributor Author

It is only useful when using a string column, not a query function. If you pass a column name, it does apply.

hmmm...but when passing a column name, the column and sort direction was applied to the query before it reached this method. And when it was a query and reached this method then it wouldn't be applied...at least in my testing.

Want to make sure I'm testing against all the different scenarios to make sure this isn't breaking anything.

@danharrin
Copy link
Member

Just tested and the second param does still seem to work when passing a column name like ->defaultSort('name', 'desc') :)

@danharrin danharrin merged commit 42105b0 into filamentphp:3.x May 16, 2024
8 checks passed
@danharrin
Copy link
Member

Thanks for your help here!

@archilex
Copy link
Contributor Author

archilex commented May 16, 2024

Just tested and the second param does still seem to work when passing a column name like ->defaultSort('name', 'desc') :)

Yes, that all works fine. I'm referring to something different:

public function getDefaultSort(Builder $query, string $direction): string | Builder | null
{
    return $this->evaluate($this->defaultSort, [
        'direction' => $direction, // this line doesn't appear to do anything
        'query' => $query,
    ]);
}

Evaluating $direction doesn't have an affect when you pass in a query. If you pass in a query and want the query to be sorted in a different direction, you have to add it to the query itself. Again, this is how it was previously too.

So my question is, since it appears that $direction doesnt do anything here in ->evaluate(), can we just remove it from being evaluated (and also passed into getDefaultSort()? (We wouldn't remove it from ->defaultSort() of course since that's needed for string columns).

@danharrin
Copy link
Member

It gives the user access to it:

->defaultSort(fn ($query, $direction) => $query->orderBy('name', $direction))

If they are sharing the function between multiple defaultSort() calls with different directions :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

None yet

3 participants