defmodule LayoutBuilder.Layout.Layout do use Ecto.Schema import Ecto.Changeset alias LayoutBuilder.Layout.Row @moduledoc """ Layout represents a Layout built by the Layout Builder. """ @type t() :: %__MODULE__{ id: Ecto.UUID.t() | nil, name: String.t(), rows: list(Row.t()) | nil, } embedded_schema do field :name, :string embeds_many :rows, Row end def changeset(%__MODULE__{} = struct, attrs) do change(struct) |> changeset(attrs) end def changeset(%Ecto.Changeset{} = change, %__MODULE__{} = attrs) do changeset(change, Map.from_struct(attrs)) end def changeset(%Ecto.Changeset{} = change, %{} = attrs) do change |> cast(attrs, [:name]) |> cast_embed(:rows) end @spec add_col(__MODULE__.t(), Row.t()) ::__MODULE__.t() def add_col(%__MODULE__{} = layout, row) do id = row.id rows = Enum.map(layout.rows, fn %Row{id: ^id} = row -> Row.add_col(row) row -> row end) %__MODULE__{layout | rows: rows} end @spec add_row(__MODULE__.t()) :: __MODULE__.t() def add_row(%__MODULE__{} = layout) do %__MODULE__{layout | rows: layout.rows ++ [Row.build_row]} end end