Skip to content

Commit

Permalink
Merge pull request #242 from vanderhoop/travis/add-direction-to-table…
Browse files Browse the repository at this point in the history
…-col

Feature: enable custom asc/desc sort qualifiers on a per-column basis
  • Loading branch information
woylie authored Sep 26, 2023
2 parents 1970254 + 5fa2ee1 commit 5637388
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 6 deletions.
6 changes: 6 additions & 0 deletions lib/flop_phoenix.ex
Original file line number Diff line number Diff line change
Expand Up @@ -1025,6 +1025,12 @@ defmodule Flop.Phoenix do
will not be clickable.
"""

attr :directions, :any,
doc: """
An optional 2-element tuple used for custom ascending and descending sort
behavior for the column, i.e. `{:asc_nulls_last, :desc_nulls_first}`
"""

attr :show, :boolean,
doc: """
Boolean value to conditionally show the column. Defaults to `true`
Expand Down
30 changes: 26 additions & 4 deletions lib/flop_phoenix/table.ex
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ defmodule Flop.Phoenix.Table do
field={col[:field]}
label={col[:label]}
sortable={sortable?(col[:field], @meta.schema)}
directions={col[:directions]}
meta={@meta}
thead_th_attrs={
merge_attrs(@opts[:thead_th_attrs], col, :thead_th_attrs)
Expand Down Expand Up @@ -173,6 +174,7 @@ defmodule Flop.Phoenix.Table do
attr :target, :string, required: true
attr :sortable, :boolean, required: true
attr :thead_th_attrs, :list, required: true
attr :directions, :any
attr :symbol_asc, :any
attr :symbol_desc, :any
attr :symbol_unsorted, :any
Expand All @@ -183,11 +185,26 @@ defmodule Flop.Phoenix.Table do
direction = order_direction(assigns.meta.flop, assigns.field)
assigns = assign(assigns, :order_direction, direction)

sort_path_options =
if directions = assigns[:directions],
do: [directions: directions],
else: []

sort_path =
build_path(
assigns[:path],
assigns[:meta],
assigns[:field],
sort_path_options
)

assigns = assign(assigns, :sort_path, sort_path)

~H"""
<th {@thead_th_attrs} aria-sort={aria_sort(@order_direction)}>
<span {@th_wrapper_attrs}>
<.sort_link
path={build_path(@path, @meta, @field)}
path={@sort_path}
on_sort={@on_sort}
event={@event}
field={@field}
Expand Down Expand Up @@ -295,12 +312,17 @@ defmodule Flop.Phoenix.Table do
field in (module |> struct() |> Flop.Schema.sortable())
end

defp build_path(nil, _, _), do: nil
defp build_path(nil, _, _, _), do: nil

defp build_path(path, meta, field) do
defp build_path(
path,
meta,
field,
opts
) do
Flop.Phoenix.build_path(
path,
Flop.push_order(meta.flop, field),
Flop.push_order(meta.flop, field, opts),
backend: meta.backend,
for: meta.schema
)
Expand Down
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ defmodule FlopPhoenix.MixProject do
{:ex_machina, "~> 2.4", only: :test},
{:excoveralls, "~> 0.10", only: :test},
{:floki, "~> 0.34.0", only: :test},
{:flop, "~> 0.22.0"},
{:flop, "~> 0.23.0"},
{:jason, "~> 1.0", only: [:dev, :test]},
{:makeup_diff, "~> 0.1.0", only: :dev, runtime: false},
{:phoenix, "~> 1.6.0 or ~> 1.7.0"},
Expand Down
2 changes: 1 addition & 1 deletion mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"excoveralls": {:hex, :excoveralls, "0.17.1", "83fa7906ef23aa7fc8ad7ee469c357a63b1b3d55dd701ff5b9ce1f72442b2874", [:mix], [{:castore, "~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "95bc6fda953e84c60f14da4a198880336205464e75383ec0f570180567985ae0"},
"file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"},
"floki": {:hex, :floki, "0.34.3", "5e2dcaec5d7c228ce5b1d3501502e308b2d79eb655e4191751a1fe491c37feac", [:mix], [], "hexpm", "9577440eea5b97924b4bf3c7ea55f7b8b6dce589f9b28b096cc294a8dc342341"},
"flop": {:hex, :flop, "0.22.1", "4eb5dc1c159845e31d33cd8e73e249b84d013d3b9b1fb17619e70d55fbd2b025", [:mix], [{:ecto, "~> 3.10.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:nimble_options, "~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}], "hexpm", "2f212238d92a8fcc2adadf20dcd875c6f8b4e1ce38ca6bc3f805918a5be567e4"},
"flop": {:hex, :flop, "0.23.0", "68b07840df6dc6fc53682097f3838c8ea5b6806642c41651a2d5da85f7e676b1", [:mix], [{:ecto, "~> 3.10.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:nimble_options, "~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}], "hexpm", "0521d0cbd58433607b9e9c77e065cc00eeb6ffdacd8fa1ed009366386f72d6c0"},
"jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"},
"makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"},
"makeup_diff": {:hex, :makeup_diff, "0.1.0", "5be352b6aa6f07fa6a236e3efd7ba689a03f28fb5d35b7a0fa0a1e4a64f6d8bb", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "186bad5bb433a8afeb16b01423950e440072284a4103034ca899180343b9b4ac"},
Expand Down
58 changes: 58 additions & 0 deletions test/flop_phoenix_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2176,6 +2176,64 @@ defmodule Flop.PhoenixTest do
assert Jason.decode!(phx_click) == [["push", %{"event" => "sort"}]]
end

test "application of custom sort directions per column" do
assigns = %{
meta: %Flop.Meta{
flop: %Flop{
order_by: [:ttfb],
order_directions: [:desc_nulls_last]
}
},
items: [
%{
ttfb: 2
},
%{
ttfb: 1
},
%{
ttfb: nil
}
],
ttfb_directions: {:asc_nulls_last, :desc_nulls_last}
}

html =
~H"""
<Flop.Phoenix.table
id="metrics-table"
items={@items}
meta={@meta}
path="/navigations"
>
<:col
:let={navigation}
label="TTFB"
field={:ttfb}
directions={@ttfb_directions}
>
<%= navigation.ttfb %>
</:col>
</Flop.Phoenix.table>
"""
|> rendered_to_string()
|> Floki.parse_fragment!()

[ttfb_sort_href] =
html
|> Floki.find("thead th a:fl-contains('TTFB')")
|> Floki.attribute("href")

%URI{query: query} = URI.parse(ttfb_sort_href)
decoded_query = Query.decode(query)

# assert href representing opposite direction of initial table sort
assert %{
"order_by" => ["ttfb"],
"order_directions" => ["asc_nulls_last"]
} = decoded_query
end

test "supports a function/args tuple as path" do
html = render_table(%{path: {&route_helper/3, @route_helper_opts}})
assert [a] = Floki.find(html, "th a:fl-contains('Name')")
Expand Down

0 comments on commit 5637388

Please sign in to comment.