Skip to content

Commit

Permalink
feat: Adding position field and functions to change the position afte…
Browse files Browse the repository at this point in the history
…r adding a new item. #145
  • Loading branch information
LuchoTurtle committed Mar 30, 2023
1 parent 623cbd5 commit 7d5a8be
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 2 deletions.
55 changes: 53 additions & 2 deletions lib/app/item.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ defmodule App.Item do
field :person_id, :integer
field :status, :integer
field :text, :string
field :position, :integer

has_many :timer, Timer
many_to_many(:tags, Tag, join_through: ItemTag, on_replace: :delete)
Expand Down Expand Up @@ -51,7 +52,11 @@ defmodule App.Item do
"""
def create_item(attrs) do
%Item{}

## Make room at beginning of list first.
reorder_list_after_adding_item(%Item{position: -1})

%Item{position: 0}
|> changeset(attrs)
|> PaperTrail.insert(originator: %{id: Map.get(attrs, :person_id, 0)})
end
Expand All @@ -68,7 +73,11 @@ defmodule App.Item do
{:error, %Ecto.Changeset{}}
"""
def create_item_with_tags(attrs) do
%Item{}

## Make room at beginning of list first.
reorder_list_after_adding_item(%Item{position: -1})

%Item{position: 0}
|> changeset_with_tags(attrs)
|> PaperTrail.insert(originator: %{id: Map.get(attrs, :person_id, 0)})
end
Expand Down Expand Up @@ -186,6 +195,48 @@ defmodule App.Item do
|> Repo.update()
end


@doc """
Moves the item from a X position to Y position.
It does this by reordering the list.
Please see method #1 of
https://betterprogramming.pub/the-best-way-to-update-a-drag-and-drop-sorting-list-through-database-schemas-31bed7371cd0
"""
def move_item(item_id, to_position) do
item = get_item!(item_id)
placeholder = %Item{item | position: to_position}

Repo.transaction(fn ->
reorder_list_after_removing_item(item)
reorder_list_after_adding_item(placeholder)
update_item(item, %{position: to_position})
end)
end

defp reorder_list_after_adding_item(%Item{position: position}) do
# Increments the positions above a given position.
# We are making space for the item to be added.

from(i in Item,
where: i.position > ^position,
update: [inc: [position: 1]]
)
|> Repo.update_all([])
end

defp reorder_list_after_removing_item(%Item{position: position}) do
# Decrements the positions above a given position.
# We are making all the positions above the given position decrement so they stay sequential.

from(i in Item,
where: i.position > ^position,
update: [inc: [position: -1]]
)
|> Repo.update_all([])
end


# 🐲 H E R E B E D R A G O N S! 🐉
# ⏳ Working with Time is all Dragons! 🙄
# 👩‍💻 Feedback/Pairing/Refactoring Welcome! 🙏
Expand Down
1 change: 1 addition & 0 deletions priv/repo/migrations/20220627162154_create_items.exs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ defmodule App.Repo.Migrations.CreateItems do
add(:text, :string)
add(:person_id, :integer)
add(:status, :integer)
add(:position, :integer)

timestamps()
end
Expand Down

0 comments on commit 7d5a8be

Please sign in to comment.