add steps
This commit is contained in:
		| @@ -6,7 +6,7 @@ defmodule Memex.Pipelines.Pipeline do | ||||
|   import Ecto.Changeset | ||||
|   import MemexWeb.Gettext | ||||
|   alias Ecto.{Changeset, UUID} | ||||
|   alias Memex.{Accounts.User, Pipelines.Step} | ||||
|   alias Memex.{Accounts.User, Pipelines.Steps.Step} | ||||
|  | ||||
|   @primary_key {:id, :binary_id, autogenerate: true} | ||||
|   @foreign_key_type :binary_id | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| defmodule Memex.Pipelines.Step do | ||||
| defmodule Memex.Pipelines.Steps.Step do | ||||
|   @moduledoc """ | ||||
|   Represents a step taken while executing a pipeline | ||||
|   """ | ||||
| @@ -46,16 +46,25 @@ defmodule Memex.Pipelines.Step do | ||||
|     |> validate_required([:title, :content, :user_id, :position]) | ||||
|   end | ||||
|  | ||||
|   @spec update_changeset(t(), attrs :: map(), position :: non_neg_integer(), User.t()) :: | ||||
|   @spec update_changeset(t(), attrs :: map(), User.t()) :: | ||||
|           changeset() | ||||
|   def update_changeset( | ||||
|         %{user_id: user_id} = step, | ||||
|         attrs, | ||||
|         position, | ||||
|         %User{id: user_id} | ||||
|       ) do | ||||
|     step | ||||
|     |> cast(attrs, [:title, :content]) | ||||
|     |> validate_required([:title, :content, :user_id, :position]) | ||||
|   end | ||||
|  | ||||
|   @spec position_changeset(t(), position :: non_neg_integer(), User.t()) :: changeset() | ||||
|   def position_changeset( | ||||
|         %{user_id: user_id} = step, | ||||
|         position, | ||||
|         %User{id: user_id} | ||||
|       ) do | ||||
|     step | ||||
|     |> change(position: position) | ||||
|     |> validate_required([:title, :content, :user_id, :position]) | ||||
|   end | ||||
|   | ||||
| @@ -4,8 +4,9 @@ defmodule Memex.Pipelines.Steps do | ||||
|   """ | ||||
|  | ||||
|   import Ecto.Query, warn: false | ||||
|   alias Ecto.Multi | ||||
|   alias Memex.{Accounts.User, Repo} | ||||
|   alias Memex.Pipelines.{Pipeline, Step} | ||||
|   alias Memex.Pipelines.{Pipeline, Steps.Step} | ||||
|  | ||||
|   @doc """ | ||||
|   Returns the list of steps. | ||||
| @@ -105,11 +106,11 @@ defmodule Memex.Pipelines.Steps do | ||||
|       {:error, %Ecto.Changeset{}} | ||||
|  | ||||
|   """ | ||||
|   @spec update_step(Step.t(), attrs :: map(), position :: non_neg_integer(), User.t()) :: | ||||
|   @spec update_step(Step.t(), attrs :: map(), User.t()) :: | ||||
|           {:ok, Step.t()} | {:error, Step.changeset()} | ||||
|   def update_step(%Step{} = step, attrs, position, user) do | ||||
|   def update_step(%Step{} = step, attrs, user) do | ||||
|     step | ||||
|     |> Step.update_changeset(attrs, position, user) | ||||
|     |> Step.update_changeset(attrs, user) | ||||
|     |> Repo.update() | ||||
|   end | ||||
|  | ||||
| @@ -130,11 +131,31 @@ defmodule Memex.Pipelines.Steps do | ||||
|   """ | ||||
|   @spec delete_step(Step.t(), User.t()) :: {:ok, Step.t()} | {:error, Step.changeset()} | ||||
|   def delete_step(%Step{user_id: user_id} = step, %{id: user_id}) do | ||||
|     step |> Repo.delete() | ||||
|     delete_step(step) | ||||
|   end | ||||
|  | ||||
|   def delete_step(%Step{} = step, %{role: :admin}) do | ||||
|     step |> Repo.delete() | ||||
|     delete_step(step) | ||||
|   end | ||||
|  | ||||
|   defp delete_step(step) do | ||||
|     Multi.new() | ||||
|     |> Multi.delete(:delete_step, step) | ||||
|     |> Multi.update_all( | ||||
|       :reorder_steps, | ||||
|       fn %{delete_step: %{position: position, pipeline_id: pipeline_id}} -> | ||||
|         from s in Step, | ||||
|           where: s.pipeline_id == ^pipeline_id, | ||||
|           where: s.position > ^position, | ||||
|           update: [set: [position: s.position - 1]] | ||||
|       end, | ||||
|       [] | ||||
|     ) | ||||
|     |> Repo.transaction() | ||||
|     |> case do | ||||
|       {:ok, %{delete_step: step}} -> {:ok, step} | ||||
|       {:error, :delete_step, changeset, _changes_so_far} -> {:error, changeset} | ||||
|     end | ||||
|   end | ||||
|  | ||||
|   @doc """ | ||||
| @@ -149,11 +170,69 @@ defmodule Memex.Pipelines.Steps do | ||||
|       %Ecto.Changeset{data: %Step{}} | ||||
|  | ||||
|   """ | ||||
|   @spec change_step(Step.t(), position :: non_neg_integer(), Pipeline.t(), User.t()) :: | ||||
|           Step.changeset() | ||||
|   @spec change_step(Step.t(), attrs :: map(), position :: non_neg_integer(), User.t()) :: | ||||
|           Step.changeset() | ||||
|   def change_step(%Step{} = step, attrs \\ %{}, position, user) do | ||||
|     step |> Step.update_changeset(attrs, position, user) | ||||
|   @spec change_step(Step.t(), User.t()) :: Step.changeset() | ||||
|   @spec change_step(Step.t(), attrs :: map(), User.t()) :: Step.changeset() | ||||
|   def change_step(%Step{} = step, attrs \\ %{}, user) do | ||||
|     step |> Step.update_changeset(attrs, user) | ||||
|   end | ||||
|  | ||||
|   @spec reorder_step(Step.t(), :up | :down, User.t()) :: | ||||
|           {:ok, Step.t()} | {:error, Step.changeset()} | ||||
|   def reorder_step(%Step{position: 0} = step, :up, _user), do: {:error, step} | ||||
|  | ||||
|   def reorder_step( | ||||
|         %Step{position: position, pipeline_id: pipeline_id, user_id: user_id} = step, | ||||
|         :up, | ||||
|         %{id: user_id} = user | ||||
|       ) do | ||||
|     Multi.new() | ||||
|     |> Multi.update_all( | ||||
|       :reorder_steps, | ||||
|       from(s in Step, | ||||
|         where: s.pipeline_id == ^pipeline_id, | ||||
|         where: s.position == ^position - 1, | ||||
|         update: [set: [position: ^position]] | ||||
|       ), | ||||
|       [] | ||||
|     ) | ||||
|     |> Multi.update( | ||||
|       :update_step, | ||||
|       step |> Step.position_changeset(position - 1, user) | ||||
|     ) | ||||
|     |> Repo.transaction() | ||||
|     |> case do | ||||
|       {:ok, %{update_step: step}} -> {:ok, step} | ||||
|       {:error, :update_step, changeset, _changes_so_far} -> {:error, changeset} | ||||
|     end | ||||
|   end | ||||
|  | ||||
|   def reorder_step( | ||||
|         %Step{pipeline_id: pipeline_id, position: position, user_id: user_id} = step, | ||||
|         :down, | ||||
|         %{id: user_id} = user | ||||
|       ) do | ||||
|     Multi.new() | ||||
|     |> Multi.one( | ||||
|       :step_count, | ||||
|       from(s in Step, where: s.pipeline_id == ^pipeline_id, distinct: true, select: count(s.id)) | ||||
|     ) | ||||
|     |> Multi.update_all( | ||||
|       :reorder_steps, | ||||
|       from(s in Step, | ||||
|         where: s.pipeline_id == ^pipeline_id, | ||||
|         where: s.position == ^position + 1, | ||||
|         update: [set: [position: ^position]] | ||||
|       ), | ||||
|       [] | ||||
|     ) | ||||
|     |> Multi.update(:update_step, fn %{step_count: step_count} -> | ||||
|       new_position = if position >= step_count - 1, do: position, else: position + 1 | ||||
|       step |> Step.position_changeset(new_position, user) | ||||
|     end) | ||||
|     |> Repo.transaction() | ||||
|     |> case do | ||||
|       {:ok, %{update_step: step}} -> {:ok, step} | ||||
|       {:error, :update_step, changeset, _changes_so_far} -> {:error, changeset} | ||||
|     end | ||||
|   end | ||||
| end | ||||
|   | ||||
		Reference in New Issue
	
	Block a user