fix(members): restore column visibility from URL on reload
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
Read 'fields' from URI when conn.params has no query (e.g. full page load). When ?fields=... is present use URL-only selection so columns are not merged with global settings. Fall back to session+global when URL has only invalid field names.
This commit is contained in:
parent
e86c78a0dc
commit
d41d13d122
2 changed files with 86 additions and 15 deletions
|
|
@ -615,7 +615,9 @@ defmodule MvWeb.MemberLive.Index do
|
|||
# -----------------------------------------------------------------
|
||||
|
||||
@impl true
|
||||
def handle_params(params, _url, socket) do
|
||||
def handle_params(params, url, socket) do
|
||||
url = url || request_url_from_socket(socket)
|
||||
params = merge_fields_param_from_uri(params, url)
|
||||
prev_sig = build_signature(socket)
|
||||
|
||||
fields_in_url? =
|
||||
|
|
@ -625,20 +627,7 @@ defmodule MvWeb.MemberLive.Index do
|
|||
end
|
||||
|
||||
url_selection = FieldSelection.parse_from_url(params)
|
||||
|
||||
merged_selection =
|
||||
FieldSelection.merge_sources(
|
||||
url_selection,
|
||||
socket.assigns.user_field_selection,
|
||||
%{}
|
||||
)
|
||||
|
||||
final_selection =
|
||||
FieldVisibility.merge_with_global_settings(
|
||||
merged_selection,
|
||||
socket.assigns.settings,
|
||||
socket.assigns.all_custom_fields
|
||||
)
|
||||
final_selection = compute_final_field_selection(fields_in_url?, url_selection, socket)
|
||||
|
||||
visible_member_fields =
|
||||
final_selection
|
||||
|
|
@ -828,6 +817,69 @@ defmodule MvWeb.MemberLive.Index do
|
|||
add_boolean_filters(base_params, boolean_filters)
|
||||
end
|
||||
|
||||
defp compute_final_field_selection(true, url_selection, socket) do
|
||||
only_url =
|
||||
FieldVisibility.selection_from_url_only(url_selection, socket.assigns.all_custom_fields)
|
||||
|
||||
visible = FieldVisibility.get_visible_member_fields(only_url)
|
||||
|
||||
if visible == [] do
|
||||
# URL had only invalid field names; fall back to session + global.
|
||||
compute_final_field_selection(false, url_selection, socket)
|
||||
else
|
||||
only_url
|
||||
end
|
||||
end
|
||||
|
||||
defp compute_final_field_selection(false, url_selection, socket) do
|
||||
merged =
|
||||
FieldSelection.merge_sources(
|
||||
url_selection,
|
||||
socket.assigns.user_field_selection,
|
||||
%{}
|
||||
)
|
||||
|
||||
FieldVisibility.merge_with_global_settings(
|
||||
merged,
|
||||
socket.assigns.settings,
|
||||
socket.assigns.all_custom_fields
|
||||
)
|
||||
end
|
||||
|
||||
# On full page load conn.params has no query string; read "fields" from URI so column visibility is restored.
|
||||
defp request_url_from_socket(socket) do
|
||||
case socket.private[:connect_info] do
|
||||
%Plug.Conn{} = conn -> Plug.Conn.request_url(conn)
|
||||
_ -> nil
|
||||
end
|
||||
end
|
||||
|
||||
defp merge_fields_param_from_uri(params, nil), do: params
|
||||
|
||||
defp merge_fields_param_from_uri(params, %URI{query: query}) when is_binary(query) do
|
||||
case URI.decode_query(query)["fields"] do
|
||||
nil -> params
|
||||
value -> Map.put(params, "fields", value)
|
||||
end
|
||||
end
|
||||
|
||||
defp merge_fields_param_from_uri(params, %URI{}), do: params
|
||||
|
||||
defp merge_fields_param_from_uri(params, url) when is_binary(url) do
|
||||
case URI.parse(url).query do
|
||||
nil ->
|
||||
params
|
||||
|
||||
q ->
|
||||
case URI.decode_query(q)["fields"] do
|
||||
nil -> params
|
||||
value -> Map.put(params, "fields", value)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
defp merge_fields_param_from_uri(params, _), do: params
|
||||
|
||||
defp build_base_params(query, sort_field, sort_order) do
|
||||
%{
|
||||
"query" => query || "",
|
||||
|
|
|
|||
|
|
@ -64,6 +64,25 @@ defmodule MvWeb.MemberLive.Index.FieldVisibility do
|
|||
member_fields ++ custom_field_names
|
||||
end
|
||||
|
||||
@doc """
|
||||
Builds field selection from URL only: fields in `url_selection` are visible, all others false.
|
||||
Use when `?fields=...` is in the URL so column visibility is not merged with global settings.
|
||||
"""
|
||||
@spec selection_from_url_only(%{String.t() => boolean()}, [struct()]) :: %{
|
||||
String.t() => boolean()
|
||||
}
|
||||
def selection_from_url_only(url_selection, custom_fields) when is_map(url_selection) do
|
||||
all_fields = get_all_available_fields(custom_fields)
|
||||
|
||||
Enum.reduce(all_fields, %{}, fn field, acc ->
|
||||
field_string = field_to_string(field)
|
||||
visible = Map.get(url_selection, field_string, false)
|
||||
Map.put(acc, field_string, visible)
|
||||
end)
|
||||
end
|
||||
|
||||
def selection_from_url_only(_, _), do: %{}
|
||||
|
||||
@doc """
|
||||
Merges user field selection with global settings.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue