134 lines
3.5 KiB
Elixir
134 lines
3.5 KiB
Elixir
defmodule BDS.Desktop.ShellLive.SidebarState do
|
|
@moduledoc false
|
|
|
|
def merge_ui_state(socket, view_id, sidebar_data) do
|
|
filters = Map.get(sidebar_data, :filters)
|
|
|
|
if is_map(filters) and Map.get(filters, :enabled) do
|
|
panel_state = filter_panel_state(socket, view_id)
|
|
|
|
Map.put(
|
|
sidebar_data,
|
|
:filters,
|
|
Map.merge(filters, %{
|
|
filter_panel_visible: panel_state.visible,
|
|
archive_collapsed: panel_state.archive_collapsed,
|
|
tags_collapsed: panel_state.tags_collapsed,
|
|
categories_collapsed: panel_state.categories_collapsed,
|
|
expanded_year: panel_state.expanded_year
|
|
})
|
|
)
|
|
else
|
|
sidebar_data
|
|
end
|
|
end
|
|
|
|
def put_filter_panel_state(socket, updater) do
|
|
view_id = Atom.to_string(socket.assigns.workbench.active_view)
|
|
state = socket |> filter_panel_state(view_id) |> updater.()
|
|
|
|
Phoenix.Component.assign(
|
|
socket,
|
|
:sidebar_filter_panels,
|
|
Map.put(socket.assigns.sidebar_filter_panels, view_id, state)
|
|
)
|
|
end
|
|
|
|
def current_filters(socket, view_id) do
|
|
socket.assigns.sidebar_filters_by_view
|
|
|> Map.get(view_id, %{})
|
|
|> normalize_filters(socket.assigns[:sidebar_data])
|
|
end
|
|
|
|
def put_filters(socket, updater) do
|
|
view_id = Atom.to_string(socket.assigns.workbench.active_view)
|
|
|
|
filters =
|
|
current_filters(socket, view_id)
|
|
|> updater.()
|
|
|> normalize_filters(socket.assigns.sidebar_data)
|
|
|
|
Phoenix.Component.assign(
|
|
socket,
|
|
:sidebar_filters_by_view,
|
|
Map.put(socket.assigns.sidebar_filters_by_view, view_id, filters)
|
|
)
|
|
end
|
|
|
|
def toggle_filter_value(filters, key, value) do
|
|
values = Map.get(filters, key, [])
|
|
|
|
next_values =
|
|
if value in values do
|
|
List.delete(values, value)
|
|
else
|
|
values ++ [value]
|
|
end
|
|
|
|
Map.put(filters, key, next_values)
|
|
end
|
|
|
|
def normalize_filter_string(nil), do: nil
|
|
|
|
def normalize_filter_string(value) do
|
|
value
|
|
|> to_string()
|
|
|> String.trim()
|
|
|> case do
|
|
"" -> nil
|
|
trimmed -> trimmed
|
|
end
|
|
end
|
|
|
|
def parse_optional_integer(nil), do: nil
|
|
def parse_optional_integer(value) when is_integer(value), do: value
|
|
|
|
def parse_optional_integer(value) when is_binary(value) do
|
|
case Integer.parse(value) do
|
|
{parsed, _rest} -> parsed
|
|
:error -> nil
|
|
end
|
|
end
|
|
|
|
def sidebar_page_size(nil), do: 500
|
|
|
|
def sidebar_page_size(sidebar_data) do
|
|
sidebar_data
|
|
|> Map.get(:filters, %{})
|
|
|> Map.get(:max_items, 500)
|
|
end
|
|
|
|
defp filter_panel_state(socket, view_id) do
|
|
default_state = default_filter_panel_state()
|
|
|
|
case Map.get(socket.assigns.sidebar_filter_panels, view_id) do
|
|
state when is_map(state) -> Map.merge(default_state, state)
|
|
visible when is_boolean(visible) -> Map.put(default_state, :visible, visible)
|
|
_other -> default_state
|
|
end
|
|
end
|
|
|
|
defp default_filter_panel_state do
|
|
%{
|
|
visible: false,
|
|
archive_collapsed: true,
|
|
tags_collapsed: true,
|
|
categories_collapsed: true,
|
|
expanded_year: nil
|
|
}
|
|
end
|
|
|
|
defp normalize_filters(filters, sidebar_data) do
|
|
max_items = sidebar_page_size(sidebar_data)
|
|
|
|
%{
|
|
search: normalize_filter_string(Map.get(filters, :search)),
|
|
year: Map.get(filters, :year),
|
|
month: Map.get(filters, :month),
|
|
tags: Map.get(filters, :tags, []),
|
|
categories: Map.get(filters, :categories, []),
|
|
display_limit: max(Map.get(filters, :display_limit, max_items) || max_items, max_items)
|
|
}
|
|
end
|
|
end
|