add steps

This commit is contained in:
2022-11-26 21:26:21 -05:00
parent 1ba5b9ec41
commit 8fcbb7aced
14 changed files with 727 additions and 66 deletions

View File

@ -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

View File

@ -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

View File

@ -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