Current section
Files
Jump to
Current section
Files
lib/phoenix_kit/modules/emails/table_columns.ex
defmodule PhoenixKit.Modules.Emails.TableColumns do
@moduledoc """
Manages table column customization for email logs display.
Provides functionality to:
- Define available columns for email logs table
- Load user's column preferences from Settings
- Save column preferences to Settings
- Reorder columns via drag-and-drop
Column preferences are stored in Settings under the key "emails_table_columns".
"""
alias PhoenixKit.Settings
@default_columns ["to", "subject", "status", "details", "actions"]
@required_columns ["to", "actions"]
@doc """
Returns all available columns for email logs table with metadata.
Column structure:
- `field`: Database field name
- `label`: Display label in UI
- `type`: Data type (:string, :datetime, :badge, :actions, :activity_events, :details_composite)
- `required`: Cannot be hidden if true
## Examples
iex> PhoenixKit.Modules.Emails.TableColumns.get_available_columns()
[
%{field: "to", label: "Email", type: :string, required: true},
%{field: "subject", label: "Subject", type: :string, required: true},
...
]
"""
def get_available_columns do
[
%{field: "to", label: "Email", type: :string, required: true},
%{field: "subject", label: "Subject", type: :string, required: false},
%{field: "status", label: "Status", type: :activity_events, required: false},
%{field: "details", label: "Details", type: :details_composite, required: false},
%{field: "actions", label: "Actions", type: :actions, required: true}
]
end
@doc """
Loads user's selected columns from Settings or returns defaults.
Returns list of column field names in user's preferred order.
## Examples
iex> PhoenixKit.Modules.Emails.TableColumns.get_user_table_columns()
["to", "subject", "status", "sent_at", "actions"]
"""
def get_user_table_columns do
case Settings.get_setting("emails_table_columns") do
nil ->
@default_columns
columns_json when is_binary(columns_json) ->
case Jason.decode(columns_json) do
{:ok, %{"selected" => selected}} when is_list(selected) ->
# Validate that all required columns are present
validated = ensure_required_columns(selected)
validated
_ ->
@default_columns
end
_ ->
@default_columns
end
end
@doc """
Saves user's column preferences to Settings.
## Parameters
- `selected_columns`: List of column field names in desired order
## Examples
iex> PhoenixKit.Modules.Emails.TableColumns.update_user_table_columns(["to", "subject", "status", "actions"])
{:ok, _setting}
"""
def update_user_table_columns(selected_columns) when is_list(selected_columns) do
# Ensure required columns are always included
validated_columns = ensure_required_columns(selected_columns)
columns_data = %{
"selected" => validated_columns,
"order" => validated_columns
}
case Jason.encode(columns_data) do
{:ok, json} ->
Settings.update_setting("emails_table_columns", json)
{:error, _} = error ->
error
end
end
@doc """
Reorders columns based on drag-and-drop interaction.
## Parameters
- `current_columns`: Current list of selected columns
- `params`: Map with "from" (source index) and "to" (target index)
## Examples
iex> PhoenixKit.Modules.Emails.TableColumns.reorder_columns(["to", "subject", "status"], %{"from" => 0, "to" => 2})
["subject", "status", "to"]
"""
def reorder_columns(current_columns, %{"from" => from_idx, "to" => to_idx})
when is_list(current_columns) do
from_index = String.to_integer(from_idx)
to_index = String.to_integer(to_idx)
if from_index >= 0 and from_index < length(current_columns) and
to_index >= 0 and to_index < length(current_columns) do
element = Enum.at(current_columns, from_index)
current_columns
|> List.delete_at(from_index)
|> List.insert_at(to_index, element)
else
current_columns
end
end
def reorder_columns(current_columns, _params), do: current_columns
@doc """
Resets columns to default configuration.
## Examples
iex> PhoenixKit.Modules.Emails.TableColumns.reset_columns()
["to", "subject", "status", "sent_at", "actions"]
"""
def reset_columns do
@default_columns
end
# Private Functions
defp ensure_required_columns(columns) do
# Add any missing required columns at the end
missing_required = @required_columns -- columns
(columns ++ missing_required)
|> Enum.uniq()
end
end