-
Notifications
You must be signed in to change notification settings - Fork 51
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
Select / typeahead combo for foreign key field #222
base: main
Are you sure you want to change the base?
Conversation
Quick update on this: work is still in progress. I've been working with Ash Admin's demo app, which surfaces some concepts I'm still absorbing, and has exposed some weaknesses in my implementation here. More soon. |
to reduce cognitive friction from having "query" represent what the user is typing mixed around use of Ash.Query
allow the component to work with the demo app policies
- determine related resources at an earlier step, where it can be more flexible - re-simplify template logic for form field names
Couple of vids showing this in action. Not shown is a has_many, but I could do one from a different project if desired. AshAdmin_CreateTicket_ManageRelationships.mp4AshAdmin_UpdateTicket_BelongsTo.mp4 |
There's only one failing Dialyzer check that I think might be correctable in this PR, but I'm not sure how. It works for me. It might be a language version thing? AshAdmin.Components.Resource.RelationshipField, line 163 >
<% suggestion_name =
String.replace(suggestion_name, ~r/(#{@search_term})/i, "<b>\\0</b>", [
:case_insensitive
]) %> |
Oh, it's the raw user generated data in the regex. One more commit coming right up. |
Really exciting stuff! This has a dialyzer error still. Could you show what it looks like for a |
@@ -37,6 +37,8 @@ Configure the admin dashboard for a given resource. | |||
| [`resource_group`](#admin-resource_group){: #admin-resource_group } | `atom` | | The group in the top resource dropdown that the resource appears in. | | |||
| [`show_sensitive_fields`](#admin-show_sensitive_fields){: #admin-show_sensitive_fields } | `list(atom)` | | The list of fields that should not be redacted in the admin UI even if they are marked as sensitive. | | |||
| [`show_calculations`](#admin-show_calculations){: #admin-show_calculations } | `list(atom)` | | A list of calculation that can be calculate when this resource is shown. By default, all calculations are included. | | |||
| [`label_field`](#admin-label_field){: #admin-label_field } | `atom` | | The field to use as the label when the resource appears in a relationship select or typeahead field on another resource's form. | | |||
| [`relationship_select_max_items`](#admin-relationship_select_max_items){: #admin-relationship_select_max_items } | `integer` | | The maximum number of items to show in a select field when this resource is shown as a relationship on another resource's form. If the number of related resources is higher, a typeahead selector will be used. | |
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 should have a reasonable default value, like 50-100 I think.
|
||
defp calculation(label_field, AshPostgres.DataLayer) do | ||
expr( | ||
fragment( |
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 think we can use contains(^ref(label_field), ^search_term)
instead of this I think.
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 not, I'd like to add a starts_with
expression to core
to make this work 😄
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.
The calculation is used to rank results based on the position of the search term in the matched result. I kinda thought it made for neat UI, in case all the user can do is guess at keywords in a large data set, but maybe that's overkill.
If I'm understanding your suggestion correctly, and if you do prefer returning only results that start with the user supplied string, then I can go ahead and make that change.
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 also don't mind contributing starts_with
as you suggested, regardless of the decision for ash_admin.
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.
Right right, we should add string_position
instead of starts_with
so you can rank them the way you have here 😄
This looks great! Small comments, would you be interested in contributing |
Fixed dialyzer in |
@zachdaniel Sweet. Regarding dependencies, once this happens, would you prefer I bump the Ash version that ash_admin depends on, or put code in place to check for the string_position function and fall back to something else? I already have the latter in place, but if you like having the libraries require the latest core, I'm happy to do that as it's a bit cleaner. |
We can bump the ash version req. Too complex to play that game when there isn't really a good reason folks can't upgrade. |
@mkschell everything you need should be released now 😄 |
Apologies for discontiguous PR.
Relevant discussion points from previous (#210
zachdaniel:
netProphET:
zachdaniel:
So I learned a lot doing this, which is great. I may have gone overboard in how I implemented some of this due to my inexperience with some of the idioms. I'm also unsure about the naming choices for the DSL: admin.label_field and admin.relationship_select_max_items. Also I did not implement a minimum # of characters to wait for in the typeahead yet. It doesn't feel too terrible to me to have it start showing results after 1 keystroke (it does use a 300 ms debounce).
Contributor checklist