feat: improve field order for approvals and add seeds
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
parent
a5ce7cb921
commit
a7481f6ab1
8 changed files with 245 additions and 109 deletions
|
|
@ -128,20 +128,20 @@ defmodule MvWeb.JoinRequestLive.Show do
|
|||
|
||||
<%= if @join_request do %>
|
||||
<div class="mt-6 space-y-6 max-w-2xl">
|
||||
<%!-- Single block: all applicant-provided data in join form order --%>
|
||||
<div>
|
||||
<h2 class="text-lg font-semibold mb-2">{gettext("Request data")}</h2>
|
||||
<h2 class="text-lg font-semibold mb-2">{gettext("Applicant data")}</h2>
|
||||
<div class="border border-base-300 rounded-lg p-4 bg-base-100 space-y-2">
|
||||
<%= for {label, value} <- applicant_data_rows(@join_request, @join_form_field_ids || []) do %>
|
||||
<.field_row label={label} value={value} empty_text={gettext("Not specified")} />
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%!-- Status and review (submitted_at, status; if decided: approved/rejected at, reviewed by) --%>
|
||||
<div>
|
||||
<h2 class="text-lg font-semibold mb-2">{gettext("Status and review")}</h2>
|
||||
<div class="border border-base-300 rounded-lg p-4 bg-base-100 space-y-2">
|
||||
<.field_row label={gettext("Email")} value={@join_request.email} />
|
||||
<.field_row
|
||||
label={gettext("First name")}
|
||||
value={@join_request.first_name}
|
||||
empty_text={gettext("Not specified")}
|
||||
/>
|
||||
<.field_row
|
||||
label={gettext("Last name")}
|
||||
value={@join_request.last_name}
|
||||
empty_text={gettext("Not specified")}
|
||||
/>
|
||||
<.field_row
|
||||
label={gettext("Submitted at")}
|
||||
value={DateFormatter.format_datetime(@join_request.submitted_at)}
|
||||
|
|
@ -154,24 +154,7 @@ defmodule MvWeb.JoinRequestLive.Show do
|
|||
</.badge>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= if map_size(@join_request.form_data || %{}) > 0 do %>
|
||||
<div>
|
||||
<h2 class="text-lg font-semibold mb-2">{gettext("Additional form data")}</h2>
|
||||
<div class="border border-base-300 rounded-lg p-4 bg-base-100 space-y-2">
|
||||
<%= for {key, value} <- format_form_data(@join_request.form_data, @join_form_field_ids || []) do %>
|
||||
<.field_row label={key} value={to_string(value)} />
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= if @join_request.status in [:approved, :rejected] do %>
|
||||
<div>
|
||||
<h2 class="text-lg font-semibold mb-2">{gettext("Review information")}</h2>
|
||||
<div class="border border-base-300 rounded-lg p-4 bg-base-100 space-y-2">
|
||||
<%= if @join_request.status in [:approved, :rejected] do %>
|
||||
<%= if @join_request.approved_at do %>
|
||||
<.field_row
|
||||
label={gettext("Approved at")}
|
||||
|
|
@ -189,9 +172,9 @@ defmodule MvWeb.JoinRequestLive.Show do
|
|||
value={JoinRequestHelpers.reviewer_display(@join_request)}
|
||||
empty_text="-"
|
||||
/>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<%= if @join_request.status == :submitted do %>
|
||||
<div class="flex flex-wrap items-center justify-between gap-3 pt-2">
|
||||
|
|
@ -240,40 +223,71 @@ defmodule MvWeb.JoinRequestLive.Show do
|
|||
"""
|
||||
end
|
||||
|
||||
# Formats form_data for display in join-form order; legacy keys (not in current
|
||||
# join_form_field_ids) are appended at the end, sorted by label for stability.
|
||||
# Labels: member field keys → human-readable; UUID keys kept as-is (custom field IDs).
|
||||
defp format_form_data(nil, _ordered_field_ids), do: []
|
||||
|
||||
defp format_form_data(form_data, ordered_field_ids) when is_map(form_data) do
|
||||
# Builds a single list of {label, display_value} for all applicant-provided data in join form
|
||||
# order. Typed fields (email, first_name, last_name) and form_data are merged; legacy
|
||||
# form_data keys (not in current join form config) are appended at the end.
|
||||
defp applicant_data_rows(join_request, ordered_field_ids) do
|
||||
member_field_strings = Constants.member_fields() |> Enum.map(&Atom.to_string/1)
|
||||
form_data = join_request.form_data || %{}
|
||||
|
||||
typed = %{
|
||||
"email" => join_request.email,
|
||||
"first_name" => join_request.first_name,
|
||||
"last_name" => join_request.last_name
|
||||
}
|
||||
|
||||
# First: entries in current join form order (only keys present in form_data)
|
||||
in_order =
|
||||
ordered_field_ids
|
||||
|> Enum.filter(&Map.has_key?(form_data, &1))
|
||||
|> Enum.map(fn key ->
|
||||
value = form_data[key]
|
||||
value = Map.get(typed, key) || Map.get(form_data, key)
|
||||
label = field_key_to_label(key, member_field_strings)
|
||||
{label, value}
|
||||
{label, format_applicant_value(value)}
|
||||
end)
|
||||
|
||||
# Then: keys in form_data that are not in current settings (e.g. removed fields on old requests)
|
||||
legacy_keys =
|
||||
form_data
|
||||
|> Map.keys()
|
||||
|> Enum.reject(&(&1 in ordered_field_ids))
|
||||
|> Enum.reject(fn k ->
|
||||
k in ordered_field_ids or k in ["email", "first_name", "last_name"]
|
||||
end)
|
||||
|> Enum.sort()
|
||||
|
||||
legacy_entries =
|
||||
Enum.map(legacy_keys, fn key ->
|
||||
label = field_key_to_label(key, member_field_strings)
|
||||
{label, form_data[key]}
|
||||
{label, format_applicant_value(form_data[key])}
|
||||
end)
|
||||
|
||||
in_order ++ legacy_entries
|
||||
end
|
||||
|
||||
defp format_applicant_value(nil), do: nil
|
||||
defp format_applicant_value(""), do: nil
|
||||
defp format_applicant_value(%Date{} = date), do: DateFormatter.format_date(date)
|
||||
defp format_applicant_value(value) when is_map(value), do: format_applicant_value_from_map(value)
|
||||
defp format_applicant_value(value) when is_boolean(value),
|
||||
do: if(value, do: gettext("Yes"), else: gettext("No"))
|
||||
defp format_applicant_value(value) when is_binary(value) or is_number(value),
|
||||
do: to_string(value)
|
||||
defp format_applicant_value(value), do: to_string(value)
|
||||
|
||||
defp format_applicant_value_from_map(value) do
|
||||
raw = Map.get(value, "_union_value") || Map.get(value, "value")
|
||||
type = Map.get(value, "_union_type") || Map.get(value, "type")
|
||||
|
||||
if raw && type in ["date", :date] do
|
||||
format_applicant_value(raw)
|
||||
else
|
||||
format_applicant_value_simple(raw, value)
|
||||
end
|
||||
end
|
||||
|
||||
defp format_applicant_value_simple(raw, _value) when is_binary(raw), do: raw
|
||||
defp format_applicant_value_simple(raw, _value) when is_boolean(raw),
|
||||
do: if(raw, do: gettext("Yes"), else: gettext("No"))
|
||||
defp format_applicant_value_simple(raw, _value) when is_integer(raw), do: to_string(raw)
|
||||
defp format_applicant_value_simple(_raw, value), do: to_string(value)
|
||||
|
||||
defp field_key_to_label(key, member_field_strings) when is_binary(key) do
|
||||
if key in member_field_strings,
|
||||
do: MemberFieldsTranslations.label(String.to_existing_atom(key)),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue