From 2bd03b34a82033e1f9c292f1c997751a64e879b7 Mon Sep 17 00:00:00 2001 From: Zamith Date: Tue, 4 Mar 2025 10:46:54 +0000 Subject: [PATCH] Adds support for parameterized Ecto types Why: * If the custom type is a parameterized type, then it is not picked up by the form builder This change addresses the need by: * Supporting parameterized types in the same fashion we support non-parameterized custom types --- lib/kaffy/resource_form.ex | 22 +++++++++++++++++----- lib/kaffy/resource_schema.ex | 9 +++++++++ 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/lib/kaffy/resource_form.ex b/lib/kaffy/resource_form.ex index 4c8657c0..bd0f4551 100644 --- a/lib/kaffy/resource_form.ex +++ b/lib/kaffy/resource_form.ex @@ -384,6 +384,7 @@ defmodule Kaffy.ResourceForm do disabled: opts[:readonly], aria_describedby: field ) + _ -> text_input(form, field, class: "form-control", @@ -456,6 +457,7 @@ defmodule Kaffy.ResourceForm do case type do :id -> number_input(form, field, opts) + _ -> text_input(form, field, opts) end @@ -501,11 +503,8 @@ defmodule Kaffy.ResourceForm do def kaffy_input(conn, changeset, form, field, options) do ft = Kaffy.ResourceSchema.field_type(changeset.data.__struct__, field) - case Kaffy.Utils.is_module(ft) && Keyword.has_key?(ft.__info__(:functions), :render_form) do - true -> - ft.render_form(conn, changeset, form, field, options) - - false -> + case custom_field_type(ft) do + {:ok, :default_type} -> {error_msg, error_class} = get_field_error(changeset, field) help_text = form_help_text({field, options}) @@ -529,10 +528,23 @@ defmodule Kaffy.ResourceForm do [label_tag, field_tag, field_feeback] end + + {:ok, ft} -> + ft.render_form(conn, changeset, form, field, options) end end defp add_class(opts, class) do Keyword.update(opts, :class, class, &"#{&1} #{class}") end + + defp custom_field_type({:parameterized, {ft, _opts}}), do: custom_field_type(ft) + + defp custom_field_type(ft) do + if Kaffy.Utils.is_module(ft) && Keyword.has_key?(ft.__info__(:functions), :render_form) do + {:ok, ft} + else + {:ok, :default_type} + end + end end diff --git a/lib/kaffy/resource_schema.ex b/lib/kaffy/resource_schema.ex index 4bb9d141..fac74730 100644 --- a/lib/kaffy/resource_schema.ex +++ b/lib/kaffy/resource_schema.ex @@ -179,14 +179,21 @@ defmodule Kaffy.ResourceSchema do cond do value.__struct__ in [NaiveDateTime, DateTime, Date, Time] -> value + value.__struct__ in [Geo.Point] -> Kaffy.Utils.json().encode!(value, escape: :html_safe, pretty: true) + true -> Map.from_struct(value) |> Map.drop([:__meta__]) |> Kaffy.Utils.json().encode!(escape: :html_safe, pretty: true) end + is_tuple(ft) && elem(ft, 0) == :parameterized && + Keyword.has_key?(elem(elem(ft, 1), 0).__info__(:functions), :render_index) -> + {:parameterized, {pt, _opts}} = ft + pt.render_index(conn, schema, field, options) + Kaffy.Utils.is_module(ft) && Keyword.has_key?(ft.__info__(:functions), :render_index) -> ft.render_index(conn, schema, field, options) @@ -216,8 +223,10 @@ defmodule Kaffy.ResourceSchema do cond do value.__struct__ in [NaiveDateTime, DateTime, Date, Time] -> value + value.__struct__ in [Geo.Point] -> Kaffy.Utils.json().encode!(value, escape: :html_safe, pretty: true) + true -> Map.from_struct(value) |> Map.drop([:__meta__])