-
-
Notifications
You must be signed in to change notification settings - Fork 394
[Autocomplete]: implement group_by option on Entity Autocompleter results #481
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
Conversation
weaverryan
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi!
Really sorry for the slow review - this someone slipped past me! I've left some comments, but this is excellent work and I would love to incorporate it when you have some time to make these changes.
Thanks!
|
Hi @weaverryan 👋 Thank you for this feedback, I will make the changes following your comments. |
57f8236 to
c7996df
Compare
|
sorry for the small setback, I had some difficulties on the rebase of the branch 2.x :( I had to do a force push because of my merge error. |
7418dd6 to
c5fe12a
Compare
|
Here are the changes after rebase and the pagination supports. |
|
Hi @weaverryan, what should we do with this pr ? I have however tried to be reactive because we are waiting for this feature. |
|
Maybe if |
I think that's an excellent idea. It would make the PR a lot safer to merge 👍 |
weaverryan
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry again for being late on this. Let us know if it is possible to use the "old format" if group_by is not set.
Cheers!
| /** | ||
| * Return group_by option. | ||
| */ | ||
| public function getGroupBy(): mixed; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of physically adding this method, which would break BC, add some documentation to the top for it: https://github.com/SymfonyCasts/reset-password-bundle/blob/6601f15fce7a4934bc9570f76feaf1b93536b1a7/src/ResetPasswordHelperInterface.php#L19 - that will allow people to be aware of it, and then we will add the actual method whenever we release a new major version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also is the return value really mixed? Or is it ?string?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes i think, It can be string, callable or null
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is QUITE the long list of things :). I think we could probably just use null|string|callable. Then, if someone passes a PropertyPath or GroupBy in a form, inside of WrappedEntityTypeAutocompleter, we could "normalize" those into a string|callable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm struggling to see how to normalize this, how do you see the implementation of this normalization
c5fe12a to
28c5cea
Compare
|
Hello, I made some changes to keep the old format if the group_by option is not set. Would you have some time to give some feedback ? |
9fb1380 to
fcdafdd
Compare
weaverryan
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is VERY close now - let's push it across the finish line!
src/Autocomplete/CHANGELOG.md
Outdated
|
|
||
| ## 2.8.0 | ||
|
|
||
| - Added support for using `Option Group`: the JSON format with option groupe takes two entries |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| - Added support for using `Option Group`: the JSON format with option groupe takes two entries | |
| - Added support for using [OptionGroups](https://tom-select.js.org/examples/optgroups/). |
And then I don't think we need to show the JSON format below. 99% of people won't care about this - it's just handled for them :)
| // '(query, callback) => { ... }' syntax because, otherwise, | ||
| // the 'this.XXX' calls inside this method fail | ||
| load: function (query: string, callback: (results?: any) => void) { | ||
| load: function (query: string, callback: (options?: any, optgroups?: any) => void) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After a little digging, it looks like this callback as a type:
| load: function (query: string, callback: (options?: any, optgroups?: any) => void) { | |
| load: function (query: string, callback: TomLoadCallback) { |
The TomLoadCallback can be imported from 'tom-select/dist/types/types' like 3 other types already. Then, for the .catch() on line 154, it would become:
.catch(() => callback([], []));
to satisfy this type.
| { "value": "1", "text": "Pizza" }, | ||
| { "value": "2", "text":"Banana"} | ||
| ] | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change is not valid anymore, right?
And we need docs for the new option :)
| $results[] = [ | ||
| 'value' => $autocompleter->getValue($entity), | ||
| 'text' => $autocompleter->getLabel($entity), | ||
| ]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor, but I think we should "exit early" first if there is no group by. Basically:
if (null === $groupBy = $autocompleter->getGroupBy()) {
// use the old logic
$results = [];
foreach ($paginator as $entity) {
$results[] = [
'value' => $autocompleter->getValue($entity),
'text' => $autocompleter->getLabel($entity),
];
}
return $results;
}Then the code that handles $groupBy can continue without needing to be in an else statement (no else will be needed at all).
| /** | ||
| * Return group_by option. | ||
| */ | ||
| public function getGroupBy(): mixed; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is QUITE the long list of things :). I think we could probably just use null|string|callable. Then, if someone passes a PropertyPath or GroupBy in a form, inside of WrappedEntityTypeAutocompleter, we could "normalize" those into a string|callable.
| } | ||
| } | ||
|
|
||
| if (\is_callable($groupBy)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it's not a callable at this point, that would be an error, right? I'm imagining that we check for null and string above (and for string, you're converting into a callable). So we could say:
if (!\is_callable($groupBy)) {
// then throw an exception
}| public array $results, | ||
| public array $options, | ||
| public array $optgroups, | ||
| public bool $hasNextPage, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't break BC here, even though it's unlikely to cause problems. So:
A) Rename $options back to $results
B) Move $optgroups to the final argument and make it optional
Then, let's move the getResults() logic into the controller. That'll keep this class dead-simple - just a carrier of data.
| public function __construct( | ||
| private DoctrineRegistryWrapper $managerRegistry, | ||
| private ?Security $security = null | ||
| private PropertyAccessorInterface $propertyAccessor, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To protect BC and trigger a deprecation, we can make the top of the class look something like this:
final class AutocompleteResultsExecutor
{
private PropertyAccessorInterface $propertyAccessor;
private ?Security $security;
public function __construct(
private DoctrineRegistryWrapper $managerRegistry,
$propertyAccessor,
/* Security $security = null */
) {
if ($propertyAccessor instanceof Security) {
trigger_deprecation('symfony/ux-autocomplete', '2.8.0', 'Passing a "%s" instance as the second argument of "%s()" is deprecated, pass a "%s" instance instead.', Security::class, __METHOD__, PropertyAccessorInterface::class);
$this->security = $propertyAccessor;
$this->propertyAccessor = new PropertyAccessor();
} else {
$this->propertyAccessor = $propertyAccessor;
$this->security = func_num_args() >= 3 ? func_get_arg(2) : null;
}
}99069c0 to
a5b8c55
Compare
|
Thank you @jvancoillie for this wonderful feature and your excellent work. Apologies for the slow merge on my end - but I'm super excited to happen (I just tried it locally and it was super fun) |
Add possibility to group results (with
group_byoption) on ajax autocomplete result