157 lines
4.8 KiB
Elixir
157 lines
4.8 KiB
Elixir
defmodule BDS.Desktop.ShellLive.CliSync do
|
|
@moduledoc false
|
|
|
|
import Phoenix.Component, only: [assign: 3]
|
|
|
|
alias BDS.{Media, Posts}
|
|
alias BDS.MapUtils
|
|
alias BDS.Media.Media, as: MediaRecord
|
|
alias BDS.Posts.Post
|
|
alias BDS.UI.Workbench
|
|
|
|
@doc """
|
|
Apply a CLI entity change payload to the shell socket. `reload_fun` is
|
|
called with `(socket, workbench)` to refresh derived data.
|
|
"""
|
|
@spec apply_entity_change(Phoenix.LiveView.Socket.t(), map(), (Phoenix.LiveView.Socket.t(),
|
|
map() ->
|
|
Phoenix.LiveView.Socket.t())) ::
|
|
Phoenix.LiveView.Socket.t()
|
|
def apply_entity_change(socket, payload, reload_fun) do
|
|
entity = MapUtils.attr(payload, :entity) || MapUtils.attr(payload, :entity_type)
|
|
|
|
entity_id =
|
|
MapUtils.attr(payload, :entity_id) || Map.get(payload, :entityId) ||
|
|
Map.get(payload, "entityId")
|
|
|
|
action = normalize_action(MapUtils.attr(payload, :action))
|
|
|
|
if is_binary(entity) and entity != "" and is_binary(entity_id) and entity_id != "" and
|
|
action in [:created, :updated, :deleted] do
|
|
{socket, workbench} = maybe_close_deleted_tab(socket, entity, entity_id, action)
|
|
|
|
socket
|
|
|> maybe_refresh_tab_meta(entity, entity_id, action)
|
|
|> reload_fun.(workbench)
|
|
else
|
|
socket
|
|
end
|
|
end
|
|
|
|
defp maybe_close_deleted_tab(socket, "post", post_id, :deleted) do
|
|
workbench = Workbench.close_tab(socket.assigns.workbench, :post, post_id)
|
|
|
|
socket =
|
|
socket
|
|
|> assign(:workbench, workbench)
|
|
|> assign(:shell_overlay, nil)
|
|
|> assign(:tab_meta, Map.delete(socket.assigns.tab_meta, {:post, post_id}))
|
|
|
|
{socket, workbench}
|
|
end
|
|
|
|
defp maybe_close_deleted_tab(socket, "media", media_id, :deleted) do
|
|
workbench = Workbench.close_tab(socket.assigns.workbench, :media, media_id)
|
|
|
|
socket =
|
|
socket
|
|
|> assign(:workbench, workbench)
|
|
|> assign(:shell_overlay, nil)
|
|
|> assign(:tab_meta, Map.delete(socket.assigns.tab_meta, {:media, media_id}))
|
|
|> assign(:media_editor_drafts, Map.delete(socket.assigns.media_editor_drafts, media_id))
|
|
|> assign(
|
|
:media_editor_quick_actions_open,
|
|
Map.delete(socket.assigns.media_editor_quick_actions_open, media_id)
|
|
)
|
|
|> assign(
|
|
:media_editor_post_pickers_open,
|
|
Map.delete(socket.assigns.media_editor_post_pickers_open, media_id)
|
|
)
|
|
|> assign(
|
|
:media_editor_post_picker_queries,
|
|
Map.delete(socket.assigns.media_editor_post_picker_queries, media_id)
|
|
)
|
|
|> assign(
|
|
:media_editor_save_states,
|
|
Map.delete(socket.assigns.media_editor_save_states, media_id)
|
|
)
|
|
|> assign(
|
|
:media_editor_translation_forms,
|
|
Map.delete(socket.assigns.media_editor_translation_forms, media_id)
|
|
)
|
|
|
|
{socket, workbench}
|
|
end
|
|
|
|
defp maybe_close_deleted_tab(socket, _entity, _entity_id, _action),
|
|
do: {socket, socket.assigns.workbench}
|
|
|
|
defp maybe_refresh_tab_meta(socket, "post", post_id, action)
|
|
when action in [:created, :updated] do
|
|
maybe_put_tab_meta(socket, :post, post_id, fn ->
|
|
case Posts.get_post(post_id) do
|
|
%Post{} = post ->
|
|
%{title: post.title || post.slug || post.id, subtitle: Atom.to_string(post.status)}
|
|
|
|
_other ->
|
|
nil
|
|
end
|
|
end)
|
|
end
|
|
|
|
defp maybe_refresh_tab_meta(socket, "media", media_id, action)
|
|
when action in [:created, :updated] do
|
|
maybe_put_tab_meta(socket, :media, media_id, fn ->
|
|
case Media.get_media(media_id) do
|
|
%MediaRecord{} = media ->
|
|
%{
|
|
title: media.title || media.filename || media.id,
|
|
subtitle: media.filename || media.mime_type || "media"
|
|
}
|
|
|
|
_other ->
|
|
nil
|
|
end
|
|
end)
|
|
end
|
|
|
|
defp maybe_refresh_tab_meta(socket, _entity, _entity_id, _action), do: socket
|
|
|
|
defp maybe_put_tab_meta(socket, route, entity_id, meta_fun) do
|
|
key = {route, entity_id}
|
|
|
|
if tab_present?(socket.assigns.workbench, key) or Map.has_key?(socket.assigns.tab_meta, key) do
|
|
case meta_fun.() do
|
|
%{} = fresh_meta ->
|
|
updated_meta =
|
|
Map.update(socket.assigns.tab_meta, key, fresh_meta, &Map.merge(&1, fresh_meta))
|
|
|
|
assign(socket, :tab_meta, updated_meta)
|
|
|
|
_other ->
|
|
socket
|
|
end
|
|
else
|
|
socket
|
|
end
|
|
end
|
|
|
|
defp tab_present?(%{tabs: tabs}, {route, entity_id}) do
|
|
Enum.any?(tabs, &(&1.type == route and &1.id == entity_id))
|
|
end
|
|
|
|
defp normalize_action(action) when action in [:created, :updated, :deleted], do: action
|
|
|
|
defp normalize_action(action) do
|
|
action
|
|
|> to_string()
|
|
|> String.downcase()
|
|
|> case do
|
|
"created" -> :created
|
|
"updated" -> :updated
|
|
"deleted" -> :deleted
|
|
_other -> :unknown
|
|
end
|
|
end
|
|
end
|