Current section

Files

Jump to
kaffy lib kaffy resource_schema.ex
Raw

lib/kaffy/resource_schema.ex

defmodule Kaffy.ResourceSchema do
@moduledoc false
def primary_key(schema) do
schema.__schema__(:primary_key)
end
def excluded_fields(schema) do
{pk, _, _} = schema.__schema__(:autogenerate_id)
autogenerated = schema.__schema__(:autogenerate)
case length(autogenerated) do
1 ->
[{auto_fields, _}] = autogenerated
[pk] ++ auto_fields
_ ->
[pk]
end
end
def index_fields(schema) do
fields(schema) -- fields_to_be_removed(schema)
end
def form_fields(schema) do
to_be_removed = fields_to_be_removed(schema) ++ [:id, :inserted_at, :updated_at]
IO.inspect(to_be_removed)
fields(schema) -- to_be_removed
end
def fields(schema) do
all_fields = get_all_fields(schema)
reorder_fields(all_fields, schema)
end
defp get_all_fields(schema) do
schema.__changeset__()
|> Enum.map(fn {k, _} -> k end)
end
defp fields_to_be_removed(schema) do
# if schema defines belongs_to assocations, remove assoc fields and keep their actual *_id fields.
schema.__changeset__()
|> Enum.reduce([], fn {field, type}, all ->
case type do
{:assoc, %Ecto.Association.BelongsTo{}} ->
[field | all]
{:assoc, %Ecto.Association.Has{cardinality: :many}} ->
[field | all]
{:assoc, %Ecto.Association.Has{cardinality: :one}} ->
[field | all]
_ ->
all
end
end)
end
defp reorder_fields(fields_list, schema) do
fields_list
|> reorder_field(:name, :first)
|> reorder_field(:title, :first)
|> reorder_field(:id, :first)
|> reorder_field(Kaffy.ResourceSchema.embeds(schema), :last)
|> reorder_field([:inserted_at, :updated_at], :last)
end
defp reorder_field(fields_list, [], _), do: fields_list
defp reorder_field(fields_list, [field | rest], position) do
fields_list = reorder_field(fields_list, field, position)
reorder_field(fields_list, rest, position)
end
defp reorder_field(fields_list, field, position) do
if field in fields_list do
fields_list = fields_list -- [field]
case position do
:first -> [field] ++ fields_list
:last -> fields_list ++ [field]
end
else
fields_list
end
end
def has_field_filters?(resource) do
admin_fields = Kaffy.ResourceAdmin.index(resource)
fields_with_filters =
Enum.map(admin_fields, fn f -> kaffy_field_filters(resource[:schema], f) end)
Enum.any?(fields_with_filters, fn
{_, filters} -> filters
_ -> false
end)
end
def kaffy_field_filters(_schema, {field, options}) do
{field, Map.get(options || %{}, :filters, false)}
end
def kaffy_field_filters(_, _), do: false
def kaffy_field_name(schema, {field, options}) do
default_name = kaffy_field_name(schema, field)
name = Map.get(options || %{}, :name)
cond do
is_binary(name) -> name
is_function(name) -> name.(schema)
true -> default_name
end
end
def kaffy_field_name(_schema, field) when is_atom(field) do
to_string(field) |> String.capitalize()
end
def kaffy_field_value(schema, {field, options}) do
default_value = kaffy_field_value(schema, field)
value = Map.get(options || %{}, :value)
cond do
is_map(value) && Map.has_key?(value, :__struct__) ->
if value.__struct__ in [NaiveDateTime, DateTime, Date, Time] do
value
else
Map.from_struct(value)
|> Map.drop([:__meta__])
|> Kaffy.Utils.json().encode!(escape: :html_safe, pretty: true)
end
is_binary(value) ->
value
is_function(value) ->
value.(schema)
is_map(value) ->
Kaffy.Utils.json().encode!(value, escape: :html_safe, pretty: true)
true ->
default_value
end
end
def kaffy_field_value(schema, field) when is_atom(field) do
value = Map.get(schema, field, "")
cond do
is_map(value) && Map.has_key?(value, :__struct__) ->
if value.__struct__ in [NaiveDateTime, DateTime, Date, Time] do
value
else
Map.from_struct(value)
|> Map.drop([:__meta__])
|> Kaffy.Utils.json().encode!(escape: :html_safe, pretty: true)
end
is_map(value) ->
Kaffy.Utils.json().encode!(value, escape: :html_safe, pretty: true)
true ->
value
end
end
def display_string_fields([], all), do: Enum.reverse(all) |> Enum.join(",")
def display_string_fields([{field, _} | rest], all) do
display_string_fields(rest, [field | all])
end
def display_string_fields([field | rest], all) do
display_string_fields(rest, [field | all])
end
def associations(schema) do
schema.__schema__(:associations)
end
def association(schema, name) do
schema.__schema__(:association, name)
end
def association_schema(schema, assoc) do
association(schema, assoc).queryable
end
def embeds(schema) do
schema.__schema__(:embeds)
end
def embed(schema, name) do
schema.__schema__(:embed, name)
end
def embed_struct(schema, name) do
embed(schema, name).related
end
def search_fields(resource) do
schema = resource[:schema]
Enum.filter(fields(schema), fn f -> field_type(schema, f) == :string end)
end
def filter_fields(_), do: nil
def field_type(_schema, {_, type}), do: type
def field_type(schema, field), do: schema.__schema__(:type, field)
def get_map_fields(schema) do
get_all_fields(schema)
|> Enum.filter(fn f -> field_type(schema, f) == :map end)
end
def widgets(_resource) do
[]
end
end