Skip to content

Commit 06d1cb1

Browse files
committed
Replace list and preloads options with query
1 parent a7ef793 commit 06d1cb1

File tree

8 files changed

+70
-156
lines changed

8 files changed

+70
-156
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ every aspect of a particular resource view, like the edit form.
7777
7878
* `actions` - functions that operate on a specific record
7979
* `tasks` - functions that operate on a resource as a whole
80-
* `list_with` - function used to fetch records
80+
* `query_with` - function used to fetch a batch of records
8181
* `render_with` - function used to encode field values in views
8282
* `create_with` - function used to insert a record
8383
* `update_with` - function used to update a record

README.md.eex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ every aspect of a particular resource view, like the edit form.
7777

7878
* `actions` - functions that operate on a specific record
7979
* `tasks` - functions that operate on a resource as a whole
80-
* `list_with` - function used to fetch records
80+
* `query_with` - function used to fetch a batch of records
8181
* `render_with` - function used to encode field values in views
8282
* `create_with` - function used to insert a record
8383
* `update_with` - function used to update a record

lib/live_admin.ex

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,9 @@ defmodule LiveAdmin do
2424
type: :atom,
2525
type_doc: "Ecto Repo used to query resource"
2626
],
27-
list_with: [
27+
query_with: [
2828
type: {:or, [:atom, {:tuple, [:atom, :atom]}]},
29-
type_doc:
30-
"`t:func_ref/0` returning `{records, count}` used to fetch records in Index component"
29+
type_doc: "`t:func_ref/0` returning an Ecto queryable"
3130
],
3231
render_with: [
3332
type: {:or, [:atom, {:tuple, [:atom, :atom]}]},

lib/live_admin/components/alert_bar.ex

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,13 @@ defmodule LiveAdmin.Components.AlertBar do
2020
~H"""
2121
<div id="alert-bar">
2222
<%= for {{alert, type}, index} <- Enum.with_index(@alerts) do %>
23-
<div class={"alert-bar #{type}"} id={"alert-#{index}"} phx-hook=".AlertItem" data-index={index} data-type={type}>
23+
<div
24+
class={"alert-bar #{type}"}
25+
id={"alert-#{index}"}
26+
phx-hook=".AlertItem"
27+
data-index={index}
28+
data-type={type}
29+
>
2430
<div class="alert-content">
2531
<%= if index == 0 && Enum.count(@alerts) > 1 do %>
2632
<div

lib/live_admin/components/resource/index.ex

Lines changed: 5 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -297,13 +297,10 @@ defmodule LiveAdmin.Components.Container.Index do
297297
end
298298

299299
@impl true
300-
def handle_event(
301-
"task",
302-
params = %{"name" => name},
303-
socket = %{
304-
assigns: %{session: session, resource: resource, config: config}
305-
}
306-
) do
300+
def handle_event("task", params = %{"name" => name}, socket) do
301+
session = socket.assigns.session
302+
resource = socket.assigns.resource
303+
307304
{_, m, f, _, _} =
308305
LiveAdmin.fetch_function(resource, session, :tasks, String.to_existing_atom(name))
309306

@@ -313,7 +310,7 @@ defmodule LiveAdmin.Components.Container.Index do
313310
Task.Supervisor.async_nolink(LiveAdmin.Task.Supervisor, fn ->
314311
try do
315312
case apply(m, f, [
316-
Resource.query(resource, Map.get(socket.assigns, :search), config) | args
313+
Resource.query(resource, socket.assigns.search, socket.assigns.config) | args
317314
]) do
318315
{:ok, message} ->
319316
LiveAdmin.PubSub.announce(session.id, :success, message)
@@ -438,62 +435,6 @@ defmodule LiveAdmin.Components.Container.Index do
438435
)}
439436
end
440437

441-
def handle_event("add_filter", _, socket = %{assigns: assigns}) do
442-
new_search =
443-
socket.assigns.search
444-
|> LiveAdmin.View.parse_search()
445-
|> Enum.concat([{"*", "_"}])
446-
|> Enum.map_join(" ", fn
447-
{field, param} -> "#{field}:#{param}"
448-
end)
449-
450-
{:noreply,
451-
push_patch(socket,
452-
to:
453-
route_with_params(socket.assigns,
454-
params: index_link_params(assigns, search: new_search)
455-
)
456-
)}
457-
end
458-
459-
def handle_event("remove_filter", %{"index" => i}, socket = %{assigns: assigns}) do
460-
new_search =
461-
socket.assigns.search
462-
|> LiveAdmin.View.parse_search()
463-
|> List.delete_at(i)
464-
|> Enum.map_join(" ", fn
465-
{field, param} -> "#{field}:#{param}"
466-
end)
467-
468-
{:noreply,
469-
push_patch(socket,
470-
to:
471-
route_with_params(socket.assigns,
472-
params: index_link_params(assigns, search: new_search)
473-
)
474-
)}
475-
end
476-
477-
def handle_event("update_filters", %{"filters" => filter_params}, socket = %{assigns: assigns}) do
478-
new_search =
479-
filter_params
480-
|> Map.values()
481-
|> Enum.filter(fn p -> p["param"] != "" end)
482-
|> Enum.map_join(" ", fn
483-
%{"field" => "any", "param" => param} -> "*:#{param}"
484-
%{"field" => field, "param" => param} -> "#{field}:#{param}"
485-
{field, param} -> "#{field}:#{param}"
486-
end)
487-
488-
{:noreply,
489-
push_patch(socket,
490-
to:
491-
route_with_params(socket.assigns,
492-
params: index_link_params(assigns, search: new_search)
493-
)
494-
)}
495-
end
496-
497438
defp index_link_params(assigns, overrides \\ []) do
498439
assigns
499440
|> Map.take([:search, :page, :sort_attr, :sort_dir, :prefix, :per])

lib/live_admin/resource.ex

Lines changed: 51 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ defmodule LiveAdmin.Resource do
99
> to query it, __live_admin_config__/0.
1010
"""
1111

12+
require Integer
13+
1214
import Ecto.Query
1315
import LiveAdmin
1416

@@ -22,11 +24,7 @@ defmodule LiveAdmin.Resource do
2224
"""
2325
defmacro __using__(opts) do
2426
opts_schema =
25-
LiveAdmin.base_configs_schema() ++
26-
[
27-
schema: [type: :atom, default: __CALLER__.module],
28-
preload: [type: {:or, [:keyword_list, nil]}, default: nil]
29-
]
27+
LiveAdmin.base_configs_schema() ++ [schema: [type: :atom, default: __CALLER__.module]]
3028

3129
quote bind_quoted: [opts: opts, opts_schema: opts_schema] do
3230
opts = NimbleOptions.validate!(opts, opts_schema)
@@ -56,7 +54,6 @@ defmodule LiveAdmin.Resource do
5654
def find(key, resource, prefix, repo) do
5755
resource.__live_admin_config__()
5856
|> Keyword.fetch!(:schema)
59-
|> preload(^preloads(resource))
6057
|> repo.get(key, prefix: prefix)
6158
end
6259

@@ -75,34 +72,30 @@ defmodule LiveAdmin.Resource do
7572
end
7673
end
7774

78-
def query(resource, search, config) do
79-
resource.__live_admin_config__()
80-
|> Keyword.fetch!(:schema)
81-
|> then(fn query ->
82-
case search do
83-
q when not is_nil(q) and byte_size(q) > 0 ->
84-
apply_search(query, q, fields(resource, config))
85-
86-
_ ->
87-
query
88-
end
89-
end)
90-
|> preload(^preloads(resource))
91-
end
92-
9375
def list(resource, opts, session, repo, config) do
94-
resource
95-
|> LiveAdmin.fetch_config(:list_with, config)
96-
|> case do
97-
nil ->
98-
build_list(resource, opts, session, repo, config)
76+
opts =
77+
opts
78+
|> Enum.into(%{})
79+
|> Map.put_new(:page, 1)
80+
|> Map.put_new(:per, session.index_page_size)
81+
|> Map.put_new(:sort_dir, :asc)
82+
|> Map.put_new(:sort_attr, LiveAdmin.primary_key!(resource))
9983

100-
{mod, func_name} ->
101-
apply(mod, func_name, [resource, opts, session])
84+
query =
85+
resource
86+
|> query(opts[:search], config)
87+
|> limit(^opts[:per])
88+
|> offset(^((opts[:page] - 1) * opts[:per]))
89+
|> order_by(^[{opts[:sort_dir], opts[:sort_attr]}])
10290

103-
name when is_atom(name) ->
104-
apply(resource, name, [opts, session])
105-
end
91+
{
92+
repo.all(query, prefix: opts[:prefix]),
93+
repo.aggregate(
94+
query |> exclude(:limit) |> exclude(:offset),
95+
:count,
96+
prefix: opts[:prefix]
97+
)
98+
}
10699
end
107100

108101
def change(resource, record \\ nil, params \\ %{}, config)
@@ -202,35 +195,19 @@ defmodule LiveAdmin.Resource do
202195
end
203196
end
204197

205-
defp build_list(resource, opts, session, repo, config) do
206-
opts =
207-
opts
208-
|> Enum.into(%{})
209-
|> Map.put_new(:page, 1)
210-
|> Map.put_new(:per, session.index_page_size)
211-
|> Map.put_new(:sort_dir, :asc)
212-
|> Map.put_new(:sort_attr, LiveAdmin.primary_key!(resource))
213-
214-
query =
215-
resource
216-
|> query(opts[:search], config)
217-
|> limit(^opts[:per])
218-
|> offset(^((opts[:page] - 1) * opts[:per]))
219-
|> order_by(^[{opts[:sort_dir], opts[:sort_attr]}])
220-
221-
{
222-
repo.all(query, prefix: opts[:prefix]),
223-
repo.aggregate(
224-
query |> exclude(:limit) |> exclude(:offset),
225-
:count,
226-
prefix: opts[:prefix]
227-
)
228-
}
229-
end
230-
231198
defp apply_search(query, q, fields) do
232-
q
233-
|> LiveAdmin.View.parse_search()
199+
parts = String.split(q, ~r{([^\s]*:)}, include_captures: true, trim: true)
200+
201+
if parts |> Enum.count() |> Integer.is_odd() do
202+
[{"*", q}]
203+
else
204+
parts
205+
|> Enum.map(&String.trim/1)
206+
|> Enum.chunk_every(2)
207+
|> Enum.map(fn
208+
[column, param] -> {String.replace(column, ":", ""), param}
209+
end)
210+
end
234211
|> case do
235212
field_queries when is_list(field_queries) ->
236213
field_queries
@@ -312,21 +289,28 @@ defmodule LiveAdmin.Resource do
312289

313290
defp parse_map_param(param), do: param
314291

315-
defp preloads(resource) do
292+
def query(resource, search, config) do
316293
resource.__live_admin_config__()
317-
|> Keyword.fetch!(:preload)
294+
|> Keyword.get(:query_with)
318295
|> case do
319296
nil ->
320297
resource.__live_admin_config__()
321298
|> Keyword.fetch!(:schema)
322-
|> parent_associations()
323-
|> Enum.map(& &1.field)
299+
|> then(fn query ->
300+
case search do
301+
q when not is_nil(q) and byte_size(q) > 0 ->
302+
apply_search(query, q, fields(resource, config))
303+
304+
_ ->
305+
query
306+
end
307+
end)
324308

325-
{m, f, []} ->
326-
apply(m, f, [resource])
309+
{m, f} ->
310+
apply(m, f, [resource, search] ++ args)
327311

328-
preloads when is_list(preloads) ->
329-
preloads
312+
f when is_atom(f) ->
313+
apply(resource, f, [search])
330314
end
331315
end
332316

lib/live_admin/router.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ defmodule LiveAdmin.Router do
107107
|> Keyword.put_new(:render_with, Application.get_env(:live_admin, :render_with))
108108
|> Keyword.put_new(:delete_with, Application.get_env(:live_admin, :delete_with))
109109
|> Keyword.put_new(:create_with, Application.get_env(:live_admin, :create_with))
110-
|> Keyword.put_new(:list_with, Application.get_env(:live_admin, :list_with))
110+
|> Keyword.put_new(:query_with, Application.get_env(:live_admin, :query_with))
111111
|> Keyword.put_new(:update_with, Application.get_env(:live_admin, :update_with))
112112
|> Keyword.put_new(:label_with, Application.get_env(:live_admin, :label_with))
113113
|> Keyword.put_new(:title_with, Application.get_env(:live_admin, :title_with))

lib/live_admin/view.ex

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ defmodule LiveAdmin.View do
22
use Phoenix.Component
33
use PhoenixHTMLHelpers
44

5-
require Integer
6-
75
import LiveAdmin.Components
86
import Phoenix.HTML
97

@@ -24,7 +22,8 @@ defmodule LiveAdmin.View do
2422

2523
embed_templates("components/layout/*")
2624

27-
def __mix_recompile__?, do: Path.join(__DIR__, "../../dist/js/app.js") |> File.read!() != @app_js
25+
def __mix_recompile__?,
26+
do: Path.join(__DIR__, "../../dist/js/app.js") |> File.read!() != @app_js
2827

2928
def render("layout.html", assigns), do: layout(assigns)
3029

@@ -41,21 +40,6 @@ defmodule LiveAdmin.View do
4140
def sort_param_name(field), do: :"#{field}_sort"
4241
def drop_param_name(field), do: :"#{field}_drop"
4342

44-
def parse_search(q) do
45-
parts = String.split(q, ~r{([^\s]*:)}, include_captures: true, trim: true)
46-
47-
if parts |> Enum.count() |> Integer.is_odd() do
48-
[{"*", q}]
49-
else
50-
parts
51-
|> Enum.map(&String.trim/1)
52-
|> Enum.chunk_every(2)
53-
|> Enum.map(fn
54-
[column, param] -> {String.replace(column, ":", ""), param}
55-
end)
56-
end
57-
end
58-
5943
def get_function_keys(resource, config, function) do
6044
resource
6145
|> LiveAdmin.fetch_config(function, config)

0 commit comments

Comments
 (0)