Packages

MavuContent: base-level functions to craete Content-Tree functionality in mavu_* projects

Current section

Files

Jump to
mavu_content lib clist.ex
Raw

lib/clist.ex

defmodule MavuContent.Clist do
@moduledoc """
The Content List context.
"""
import MavuContent.Ce, only: [is_ce: 1]
alias MavuContent.Ce
def append(nil, item), do: append([], item)
def append(clist, item) when is_list(clist) and is_ce(item) do
clist ++ [item]
end
def append(clist, path, item) when is_binary(path) and is_list(clist) and is_ce(item) do
path
|> get_access_list_for_path()
|> case do
[] ->
append(clist, item)
path ->
update_in(clist, path, fn items ->
append(items, item)
end)
end
end
def remove(clist, uid_to_remove) when is_list(clist) and is_binary(uid_to_remove) do
clist
|> Enum.filter(fn a -> a["uid"] != uid_to_remove end)
end
def remove(clist, uids_to_remove) when is_list(clist) and is_list(uids_to_remove) do
clist
|> Enum.filter(fn a -> not Enum.member?(uids_to_remove, a["uid"]) end)
end
def remove(clist, path, uid_or_uids)
when is_binary(path) and is_list(clist) and (is_list(uid_or_uids) or is_binary(uid_or_uids)) do
path
|> get_access_list_for_path()
|> case do
[] ->
remove(clist, uid_or_uids)
path ->
update_in(clist, path, fn items ->
remove(items, uid_or_uids)
end)
end
end
def duplicate(clist, uid) when is_list(clist) and is_binary(uid) do
clist
|> Enum.map(fn ce ->
if(ce["uid"] == uid) do
[ce, Ce.duplicate_ce(ce)]
else
[ce]
end
end)
|> Enum.concat()
end
def duplicate(clist, path, uid) when is_binary(path) and is_list(clist) and is_binary(uid) do
get_access_list_for_path(path)
|> case do
[] ->
duplicate(clist, uid)
path ->
update_in(clist, path, fn items ->
duplicate(items, uid)
end)
end
end
def get_ce(clist, path, uid) when is_list(clist) and is_binary(path) and is_binary(uid) do
get_in(clist, get_access_list_for_path_and_uid(path, uid))
|> flatten()
|> case do
[el] -> el
_ -> nil
end
end
def get_clist(clist, path) when is_list(clist) and is_binary(path) do
get_access_list_for_path(path)
|> case do
[] ->
clist
pathparts ->
get_in(clist, pathparts)
end
end
def get_access_list_for_path_and_uid(path, uid) when is_binary(uid) and is_binary(path) do
get_access_list_for_path(path) ++ [Access.filter(&(&1["uid"] == uid))]
end
def get_access_list_for_path(path) when is_binary(path) do
path
|> get_path_as_list()
|> Enum.flat_map(fn {idx, fieldname} ->
[
Access.filter(&(&1["uid"] == idx)),
Access.key(fieldname, [])
]
end)
end
def get_path_as_list(nil), do: []
def get_path_as_list(""), do: []
def get_path_as_list("-"), do: []
def get_path_as_list("root"), do: []
def get_path_as_list(path) when is_list(path), do: path
def get_path_as_list(path) when is_binary(path) do
path
|> String.trim("-")
|> String.split("-")
|> Enum.filter(fn
"root" -> false
_ -> true
end)
|> Enum.map(fn pathpart ->
pathpart
|> String.split(".")
|> List.to_tuple()
end)
end
def moveItem(fromPos, offset, list) do
offset =
case offset do
0 -> 0
offset when offset > 0 -> offset + 1
offset when offset < 0 -> offset - 1
end
list
|> Enum.with_index()
|> Enum.map(fn {item, index} ->
if index == fromPos do
{item, index + offset}
else
{item, index}
end
end)
|> Enum.sort(fn {_, index1}, {_, index2} -> index1 <= index2 end)
|> Enum.map(fn {item, _} -> item end)
end
def move(clist, uid, direction)
when is_binary(direction) and is_binary(uid) and is_list(clist) do
idx = Enum.find_index(clist, &(&1["uid"] == uid))
offset =
case direction do
"up" -> -1
"down" -> 1
_ -> 0
end
moveItem(idx, offset, clist)
end
def move(nil, _uid, _direction), do: []
def move(clist, path, uid, direction)
when is_binary(direction) and is_binary(path) and is_list(clist) and is_binary(uid) do
path
|> get_access_list_for_path()
|> case do
[] ->
move(clist, uid, direction)
path ->
update_in(clist, path, fn items ->
move(items, uid, direction)
end)
end
end
def replace(clist, path, uid, data)
when is_map(data) and is_binary(path) and is_list(clist) and is_binary(uid) do
access_list = get_access_list_for_path_and_uid(path, uid)
put_in(clist, access_list, data)
end
def replace(clist, path, data)
when is_list(data) and is_binary(path) and is_list(clist) do
case get_access_list_for_path(path) do
[] -> data
access_list -> put_in(clist, access_list, data)
end
end
def update(clist, path, uid, new_data)
when is_map(new_data) and is_binary(path) and is_list(clist) and is_binary(uid) do
access_list = get_access_list_for_path_and_uid(path, uid)
update_in(clist, access_list, fn item -> Map.merge(item, new_data) end)
end
def flatten([head | tail]), do: flatten(head) ++ flatten(tail)
def flatten([]), do: []
def flatten(element), do: [element]
def copy(clist, uids, clipboard)
when is_list(clist) and is_list(uids) do
elements_to_store =
clist
|> Enum.filter(fn a -> Enum.member?(uids, a["uid"]) end)
|> IO.inspect(label: "mwuits-debug 2021-03-11_12:53 TOSTORE")
clipboard.(:put, elements_to_store)
clist
end
def copy(clist, path, uids, clipboard)
when is_binary(path) and is_list(clist) and is_list(uids) do
path
|> get_access_list_for_path()
|> case do
[] ->
copy(clist, uids, clipboard)
path ->
update_in(clist, path, fn items ->
copy(items, uids, clipboard)
end)
end
end
def cut(clist, path, uids, clipboard)
when is_binary(path) and is_list(clist) and is_list(uids) do
copy(clist, path, uids, clipboard)
clist
|> Enum.filter(fn a -> not Enum.member?(uids, a["uid"]) end)
end
def add(clist, uid, position, new_items)
when is_list(clist) and is_list(new_items) do
new_items
|> case do
[_ | _] = new_elements ->
add_elements_to_clist(clist, new_elements, uid, position)
_ ->
clist
end
end
def add(clist, path, uid, position, new_items)
when is_list(new_items) and is_binary(path) and is_list(clist) do
path
|> get_access_list_for_path()
|> case do
[] ->
add(clist, uid, position, new_items)
path ->
update_in(clist, path, fn items ->
add(items, uid, position, new_items)
end)
end
end
def paste(clist, uid, position, clipboard)
when is_list(clist) do
clipboard.(:get, [])
|> case do
[_ | _] = new_elements ->
add_elements_to_clist(clist, renew_uids(new_elements), uid, position)
_ ->
clist
end
end
def paste(clist, path, uid, position, clipboard)
when is_binary(path) and is_list(clist) do
path
|> get_access_list_for_path()
|> case do
[] ->
paste(clist, uid, position, clipboard)
path ->
update_in(clist, path, fn items ->
paste(items, uid, position, clipboard)
end)
end
end
def add_elements_to_clist(clist, elements, uid, "before")
when is_binary(uid) and is_list(elements) and is_list(clist) do
clist
|> Enum.map(fn ce ->
if(ce["uid"] == uid) do
elements ++ [ce]
else
[ce]
end
end)
|> Enum.concat()
end
def add_elements_to_clist(clist, elements, uid, "after")
when is_binary(uid) and is_list(elements) and is_list(clist) do
clist
|> Enum.map(fn ce ->
if(ce["uid"] == uid) do
[ce] ++ elements
else
[ce]
end
end)
|> Enum.concat()
end
def add_elements_to_clist(clist, elements, uid, _) when is_binary(uid),
do: add_elements_to_clist(clist, elements, uid, "after")
def add_elements_to_clist(clist, elements, _, "start")
when is_list(elements) and is_list(clist),
do: elements ++ clist
def add_elements_to_clist(clist, elements, _, "end") when is_list(elements) and is_list(clist),
do: clist ++ elements
def add_elements_to_clist(clist, elements, _, _),
do: add_elements_to_clist(clist, elements, nil, "end")
def renew_uids(clist) when is_list(clist) do
clist
|> Enum.map(&Ce.renew_uid/1)
end
end