feat(portal): Sort resources by name ASC by default (#7884)

Updates the Resource's pagination cursor such that the default cursor
(with no HTTP params applied) uses `{:resources, :asc, :name}` as the
default, which correctly updates all Resources live tables to sort by
`name`.

The reason this is updated at the Query layer is because I wanted to
achieve this without populating URL params by default, and still
allowing the sort icon to properly reflect the default sort order upon
page load, which it does.

My initial attempt went down the path of updating `assign_live_table/3`
to take a `default_order_by` option. That didn't work because upon page
load we `handle_params` which resets the ordering immediately based on
the URL params.

Rather than update the UI code to track even more state in order to use
`default_order_by` when the `order_by` param is not specified, I opted
to updated the Query module instead which the UI uses.

Fixes #7842
This commit is contained in:
Jamil
2025-01-27 09:38:19 -08:00
committed by GitHub
parent 24640cad34
commit acfecc11ec
3 changed files with 52 additions and 0 deletions

View File

@@ -142,6 +142,7 @@ defmodule Domain.Resources.Resource.Query do
@impl Domain.Repo.Query
def cursor_fields,
do: [
{:resources, :asc, :name},
{:resources, :asc, :inserted_at},
{:resources, :asc, :id}
]

View File

@@ -0,0 +1,13 @@
defmodule Domain.Repo.Migrations.IndexResourcesOnName do
use Ecto.Migration
def change do
create(
index(
:resources,
[:account_id, :name],
where: "deleted_at IS NULL"
)
)
end
end

View File

@@ -100,6 +100,44 @@ defmodule Web.Live.Resources.IndexTest do
end)
end
test "sort alphabetically by name ASC by default", %{
account: account,
identity: identity,
conn: conn
} do
resource5 = Fixtures.Resources.create_resource(account: account, name: "Resource 5")
resource4 = Fixtures.Resources.create_resource(account: account, name: "Resource 4")
resource3 = Fixtures.Resources.create_resource(account: account, name: "Resource 3")
resource2 = Fixtures.Resources.create_resource(account: account, name: "Resource 2")
resource1 = Fixtures.Resources.create_resource(account: account, name: "Resource 1")
{:ok, lv, _html} =
conn
|> authorize_conn(identity)
|> live(~p"/#{account}/resources")
resource_rows =
lv
|> element("#resources")
|> render()
|> table_to_map()
first_row = Enum.at(resource_rows, 0)
assert first_row["name"] =~ resource1.name
second_row = Enum.at(resource_rows, 1)
assert second_row["name"] =~ resource2.name
third_row = Enum.at(resource_rows, 2)
assert third_row["name"] =~ resource3.name
fourth_row = Enum.at(resource_rows, 3)
assert fourth_row["name"] =~ resource4.name
fifth_row = Enum.at(resource_rows, 4)
assert fifth_row["name"] =~ resource5.name
end
test "renders authorized groups peek", %{
account: account,
identity: identity,