ash-project / ash_admin

A super-admin UI dashboard for Ash Framework applications, built with Phoenix LiveView.
https://hexdocs.pm/ash_admin
MIT License
106 stars 48 forks source link

select input for relationship via label_field config on destination resource POC (#209) #210

Closed netProphET closed 1 month ago

netProphET commented 1 month ago

Addition of a label_field in a destination resource configuration signals to use a select box to represent the related resource.

admin do
    label_field :admin_label
end

label_field can be a resource attribute or a calculation.

Contributor checklist

netProphET commented 1 month ago

Revised approach based on feedback to Issue #209

If I'm on the right track, I'll continue with tests and anything else that needs tidying up or documenting. I'm still a bit new to the ecosystem, so guidance is appreciated.

zachdaniel commented 1 month ago

Exciting! I'll look either this weekend or on Monday 🥳

zachdaniel commented 1 month ago

So, this is very cool, but I do worry that it can only really be used for low cardinality relationships. i.e if you had 100k users, you would need a type-ahead that would do things like fetch data after a few characters were displayed etc.

If we add this and someone misuses it, it might look good in dev but then when running in prod it could cause significant issues.

zachdaniel commented 1 month ago

Would you be open to making it a typeahead? It doesn't have to look beautiful :)

netProphET commented 1 month ago

Yeah that concern crossed my mind as well, and a typeahead could be a good solution. Definitely don't want to provide the rope to hang a production site with. However, not sure I love typeahead for the really low cardinality relationships, e.g. say you have 3 Categories to pick from. I'm happy to play around with this till we have something that will scale.

zachdaniel commented 1 month ago

I think it would make sense to do one of two things:

  1. fetch some limited number of results, and if there are less than that that come back, we show a select, and if there are more we show a typeahead.
  2. make it configurable from the outset in the source form. Like configuring it from the source.
netProphET commented 1 month ago

@zachdaniel this is coming together nicely, but I'm having difficulty with, of all things, the query for typeahead suggestions

This is the current non-working state of my function

  defp fetch_suggestions(resource, query) do
    label_field = AshAdmin.Resource.label_field(resource)
    pk_field = Ash.Resource.Info.primary_key(resource)

    resource
    |> Ash.Query.new()
    |> Ash.Query.load([pk_field, label_field])
    |> Ash.Query.filter(
      contains(
        ^label_field,
        ^%Ash.CiString{string: query}
      )
    )
    |> Ash.read!()
    |> Enum.map(&{Map.get(&1, label_field), &1.id})
  end

I can't seem to make the field name in the contains function dynamic. It works as expected if I replace ^label_field with an actual field name. I'm not sure if I should be turning to a custom action here, or if I'm just missing some syntax with the current approach. Any insight is appreciated.

zachdaniel commented 1 month ago

label_field should be ^ref(label_field)

netProphET commented 1 month ago

Excellent! Thanks. Guess I should rtfm some more ;-)