chore: convert menu editor to live component
This commit is contained in:
@@ -527,51 +527,6 @@ defmodule BDS.Desktop.ShellLive do
|
|||||||
{:noreply, apply_shell_command(socket, action)}
|
{:noreply, apply_shell_command(socket, action)}
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_event("menu_editor_select_item", %{"item_id" => item_id}, socket) do
|
|
||||||
{:noreply, MenuEditor.select_item(socket, item_id, &reload_shell/2)}
|
|
||||||
end
|
|
||||||
|
|
||||||
def handle_event("change_menu_editor_entry", %{"menu_editor_entry" => params}, socket) do
|
|
||||||
{:noreply, MenuEditor.change_entry(socket, params, &reload_shell/2)}
|
|
||||||
end
|
|
||||||
|
|
||||||
def handle_event("submit_menu_editor_entry", _params, socket) do
|
|
||||||
{:noreply, MenuEditor.submit_entry(socket, &reload_shell/2)}
|
|
||||||
end
|
|
||||||
|
|
||||||
def handle_event("cancel_menu_editor_entry", _params, socket) do
|
|
||||||
{:noreply, MenuEditor.cancel_entry(socket, &reload_shell/2)}
|
|
||||||
end
|
|
||||||
|
|
||||||
def handle_event("select_menu_editor_page", %{"post_id" => post_id}, socket) do
|
|
||||||
{:noreply, MenuEditor.select_page(socket, post_id, &reload_shell/2)}
|
|
||||||
end
|
|
||||||
|
|
||||||
def handle_event("select_menu_editor_category", %{"name" => name}, socket) do
|
|
||||||
{:noreply, MenuEditor.select_category(socket, name, &reload_shell/2)}
|
|
||||||
end
|
|
||||||
|
|
||||||
def handle_event("menu_editor_toolbar_action", %{"action" => action}, socket) do
|
|
||||||
{:noreply, MenuEditor.toolbar_action(socket, action, &reload_shell/2, &append_output_entry/5)}
|
|
||||||
end
|
|
||||||
|
|
||||||
def handle_event(
|
|
||||||
"menu_editor_drop_item",
|
|
||||||
%{
|
|
||||||
"drag_item_id" => drag_item_id,
|
|
||||||
"target_item_id" => target_item_id,
|
|
||||||
"position" => position
|
|
||||||
},
|
|
||||||
socket
|
|
||||||
) do
|
|
||||||
{:noreply,
|
|
||||||
MenuEditor.drop_item(socket, drag_item_id, target_item_id, position, &reload_shell/2)}
|
|
||||||
end
|
|
||||||
|
|
||||||
def handle_event("menu_editor_keydown", %{"key" => key}, socket) do
|
|
||||||
{:noreply, MenuEditor.handle_keydown(socket, key, &reload_shell/2)}
|
|
||||||
end
|
|
||||||
|
|
||||||
def handle_event("change_script_editor", %{"script_editor" => params}, socket) do
|
def handle_event("change_script_editor", %{"script_editor" => params}, socket) do
|
||||||
{:noreply, CodeEntityEditor.update_script(socket, params, &reload_shell/2)}
|
{:noreply, CodeEntityEditor.update_script(socket, params, &reload_shell/2)}
|
||||||
end
|
end
|
||||||
@@ -1353,6 +1308,10 @@ defmodule BDS.Desktop.ShellLive do
|
|||||||
{:noreply, reload_shell(socket, socket.assigns.workbench)}
|
{:noreply, reload_shell(socket, socket.assigns.workbench)}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def handle_info({:menu_editor_output, title, message, level}, socket) do
|
||||||
|
{:noreply, append_output_entry(socket, title, message, nil, level)}
|
||||||
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def render(assigns) do
|
def render(assigns) do
|
||||||
UILocale.put(assigns.page_language)
|
UILocale.put(assigns.page_language)
|
||||||
@@ -1423,7 +1382,6 @@ defmodule BDS.Desktop.ShellLive do
|
|||||||
|> assign(:current_tab, current_tab(workbench))
|
|> assign(:current_tab, current_tab(workbench))
|
||||||
|> assign_post_editor()
|
|> assign_post_editor()
|
||||||
|> assign_media_editor()
|
|> assign_media_editor()
|
||||||
|> assign_menu_editor()
|
|
||||||
|> assign_code_entity_editor()
|
|> assign_code_entity_editor()
|
||||||
|> assign_chat_editor()
|
|> assign_chat_editor()
|
||||||
|> assign_import_editor()
|
|> assign_import_editor()
|
||||||
@@ -1477,10 +1435,6 @@ defmodule BDS.Desktop.ShellLive do
|
|||||||
MediaEditor.assign_socket(socket)
|
MediaEditor.assign_socket(socket)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp assign_menu_editor(socket) do
|
|
||||||
MenuEditor.assign_socket(socket)
|
|
||||||
end
|
|
||||||
|
|
||||||
defp assign_code_entity_editor(socket) do
|
defp assign_code_entity_editor(socket) do
|
||||||
CodeEntityEditor.assign_socket(socket)
|
CodeEntityEditor.assign_socket(socket)
|
||||||
end
|
end
|
||||||
@@ -1658,7 +1612,8 @@ defmodule BDS.Desktop.ShellLive do
|
|||||||
end
|
end
|
||||||
|
|
||||||
defp save_current_tab(%{assigns: %{current_tab: %{type: :menu_editor}}} = socket) do
|
defp save_current_tab(%{assigns: %{current_tab: %{type: :menu_editor}}} = socket) do
|
||||||
MenuEditor.toolbar_action(socket, "save", &reload_shell/2, &append_output_entry/5)
|
send_update(MenuEditor, id: "menu-editor", action: :save)
|
||||||
|
socket
|
||||||
end
|
end
|
||||||
|
|
||||||
defp save_current_tab(%{assigns: %{current_tab: %{type: :tags}}} = socket) do
|
defp save_current_tab(%{assigns: %{current_tab: %{type: :tags}}} = socket) do
|
||||||
|
|||||||
@@ -399,8 +399,12 @@
|
|||||||
offline_mode={@offline_mode}
|
offline_mode={@offline_mode}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<% @current_tab.type == :menu_editor and @menu_editor -> %>
|
<% @current_tab.type == :menu_editor and @current_project -> %>
|
||||||
<MenuEditor.menu_editor menu_editor={@menu_editor} />
|
<.live_component module={MenuEditor} id="menu-editor"
|
||||||
|
project_id={@current_project.id}
|
||||||
|
current_tab={@current_tab}
|
||||||
|
tab_meta={@tab_meta}
|
||||||
|
/>
|
||||||
|
|
||||||
<% @current_tab.type == :tags and @current_project -> %>
|
<% @current_tab.type == :tags and @current_project -> %>
|
||||||
<.live_component module={TagsEditor} id="tags-editor" project_id={@current_project.id} current_tab={@current_tab} tab_meta={@tab_meta} />
|
<.live_component module={TagsEditor} id="tags-editor" project_id={@current_project.id} current_tab={@current_tab} tab_meta={@tab_meta} />
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
defmodule BDS.Desktop.ShellLive.MenuEditor do
|
defmodule BDS.Desktop.ShellLive.MenuEditor do
|
||||||
@moduledoc false
|
@moduledoc false
|
||||||
|
|
||||||
use Phoenix.Component
|
use Phoenix.LiveComponent
|
||||||
|
|
||||||
alias BDS.Desktop.ShellData
|
alias BDS.Desktop.ShellData
|
||||||
|
|
||||||
@@ -15,158 +15,239 @@ defmodule BDS.Desktop.ShellLive.MenuEditor do
|
|||||||
|
|
||||||
embed_templates("menu_editor_html/*")
|
embed_templates("menu_editor_html/*")
|
||||||
|
|
||||||
@spec assign_socket(term()) :: term()
|
@spec update(map(), Phoenix.LiveView.Socket.t()) :: {:ok, Phoenix.LiveView.Socket.t()}
|
||||||
def assign_socket(socket) do
|
@impl true
|
||||||
case socket.assigns[:current_tab] do
|
def update(%{action: :save} = assigns, socket) do
|
||||||
%{type: :menu_editor, id: tab_id} ->
|
socket = assign(socket, Map.drop(assigns, [:action]))
|
||||||
state = State.ensure_state(socket.assigns)
|
socket = do_save(socket)
|
||||||
menu_editor = State.build(socket.assigns, state)
|
{:ok, socket}
|
||||||
|
|
||||||
socket
|
|
||||||
|> assign(:menu_editor_state, state)
|
|
||||||
|> assign(:menu_editor, menu_editor)
|
|
||||||
|> assign(
|
|
||||||
:tab_meta,
|
|
||||||
Map.put(socket.assigns.tab_meta, {:menu_editor, tab_id}, %{
|
|
||||||
title: translated("menuEditor.tabTitle"),
|
|
||||||
subtitle: translated("menuEditor.description")
|
|
||||||
})
|
|
||||||
)
|
|
||||||
|
|
||||||
_other ->
|
|
||||||
assign(socket, :menu_editor, nil)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec select_item(term(), term(), term()) :: term()
|
def update(assigns, socket) do
|
||||||
def select_item(socket, item_id, reload) do
|
socket =
|
||||||
socket
|
socket
|
||||||
|> State.update_state(fn state -> %{state | selected_id: item_id} end)
|
|> assign(assigns)
|
||||||
|> reload.(socket.assigns.workbench)
|
|> ensure_project_assigns()
|
||||||
|
|> build_data()
|
||||||
|
|
||||||
|
{:ok, socket}
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec change_entry(term(), term(), term()) :: term()
|
@spec render(map()) :: Phoenix.LiveView.Rendered.t()
|
||||||
def change_entry(socket, params, reload) do
|
@impl true
|
||||||
|
def render(assigns) do
|
||||||
|
menu_editor(assigns)
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec handle_event(String.t(), map(), Phoenix.LiveView.Socket.t()) ::
|
||||||
|
{:noreply, Phoenix.LiveView.Socket.t()}
|
||||||
|
@impl true
|
||||||
|
def handle_event("menu_editor_select_item", %{"item_id" => item_id}, socket) do
|
||||||
|
socket =
|
||||||
|
socket
|
||||||
|
|> State.update_state(fn state -> %{state | selected_id: item_id} end)
|
||||||
|
|> build_data()
|
||||||
|
|
||||||
|
{:noreply, socket}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_event("change_menu_editor_entry", %{"menu_editor_entry" => params}, socket) do
|
||||||
query = Map.get(params, "query", "")
|
query = Map.get(params, "query", "")
|
||||||
|
|
||||||
socket
|
socket =
|
||||||
|> State.update_state(fn state -> put_in(state, [:draft, :query], query) end)
|
socket
|
||||||
|> reload.(socket.assigns.workbench)
|
|> State.update_state(fn state -> put_in(state, [:draft, :query], query) end)
|
||||||
|
|> build_data()
|
||||||
|
|
||||||
|
{:noreply, socket}
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec submit_entry(term(), term()) :: term()
|
def handle_event("submit_menu_editor_entry", _params, socket) do
|
||||||
def submit_entry(socket, reload) do
|
socket =
|
||||||
case DraftManagement.current_draft(socket.assigns) do
|
case DraftManagement.current_draft(socket.assigns) do
|
||||||
%{type: :page} ->
|
%{type: :page} ->
|
||||||
socket
|
socket
|
||||||
|> State.update_state(&DraftManagement.finalize_submenu_draft/1)
|
|> State.update_state(&DraftManagement.finalize_submenu_draft/1)
|
||||||
|> reload.(socket.assigns.workbench)
|
|> build_data()
|
||||||
|
|
||||||
%{type: :category} ->
|
%{type: :category} ->
|
||||||
socket
|
socket
|
||||||
|> DraftManagement.confirm_category_draft(&State.update_state/2)
|
|> DraftManagement.confirm_category_draft(&State.update_state/2)
|
||||||
|> reload.(socket.assigns.workbench)
|
|> build_data()
|
||||||
|
|
||||||
_other ->
|
_other ->
|
||||||
reload.(socket, socket.assigns.workbench)
|
socket
|
||||||
end
|
end
|
||||||
|
|
||||||
|
{:noreply, socket}
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec cancel_entry(term(), term()) :: term()
|
def handle_event("cancel_menu_editor_entry", _params, socket) do
|
||||||
def cancel_entry(socket, reload) do
|
socket =
|
||||||
socket
|
socket
|
||||||
|> State.update_state(&DraftManagement.cancel_draft/1)
|
|> State.update_state(&DraftManagement.cancel_draft/1)
|
||||||
|> reload.(socket.assigns.workbench)
|
|> build_data()
|
||||||
|
|
||||||
|
{:noreply, socket}
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec select_page(term(), term(), term()) :: term()
|
def handle_event("select_menu_editor_page", %{"post_id" => post_id}, socket) do
|
||||||
def select_page(socket, post_id, reload) do
|
socket =
|
||||||
case PageCategory.page_post(socket.assigns.projects.active_project_id, post_id) do
|
case PageCategory.page_post(socket.assigns.projects.active_project_id, post_id) do
|
||||||
nil ->
|
nil ->
|
||||||
reload.(socket, socket.assigns.workbench)
|
socket
|
||||||
|
|
||||||
post ->
|
post ->
|
||||||
socket
|
socket
|
||||||
|> State.update_state(&DraftManagement.assign_page_to_draft(&1, post))
|
|> State.update_state(&DraftManagement.assign_page_to_draft(&1, post))
|
||||||
|> reload.(socket.assigns.workbench)
|
|> build_data()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
{:noreply, socket}
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec select_category(term(), term(), term()) :: term()
|
def handle_event("select_menu_editor_category", %{"name" => name}, socket) do
|
||||||
def select_category(socket, name, reload) do
|
|
||||||
project_id = socket.assigns.projects.active_project_id
|
project_id = socket.assigns.projects.active_project_id
|
||||||
|
|
||||||
case Enum.find(PageCategory.category_options(project_id), &(&1.name == name)) do
|
socket =
|
||||||
nil ->
|
case Enum.find(PageCategory.category_options(project_id), &(&1.name == name)) do
|
||||||
reload.(socket, socket.assigns.workbench)
|
nil ->
|
||||||
|
socket
|
||||||
|
|
||||||
category ->
|
category ->
|
||||||
socket
|
socket
|
||||||
|> State.update_state(&DraftManagement.assign_category_to_draft(&1, category))
|
|> State.update_state(&DraftManagement.assign_category_to_draft(&1, category))
|
||||||
|> reload.(socket.assigns.workbench)
|
|> build_data()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
{:noreply, socket}
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec toolbar_action(term(), term(), term(), term()) :: term()
|
def handle_event("menu_editor_toolbar_action", %{"action" => action}, socket) do
|
||||||
def toolbar_action(socket, action, reload, append_output) do
|
socket = handle_toolbar_action(socket, action)
|
||||||
case action do
|
{:noreply, socket}
|
||||||
"add-entry" ->
|
|
||||||
socket
|
|
||||||
|> State.update_state(&DraftManagement.start_page_draft/1)
|
|
||||||
|> reload.(socket.assigns.workbench)
|
|
||||||
|
|
||||||
"add-category-archive" ->
|
|
||||||
socket
|
|
||||||
|> State.update_state(&DraftManagement.start_category_draft/1)
|
|
||||||
|> reload.(socket.assigns.workbench)
|
|
||||||
|
|
||||||
"save" ->
|
|
||||||
State.save(socket, reload, append_output)
|
|
||||||
|
|
||||||
"move-up" ->
|
|
||||||
socket
|
|
||||||
|> State.update_state(&TreeOps.move_selected(&1, :up))
|
|
||||||
|> reload.(socket.assigns.workbench)
|
|
||||||
|
|
||||||
"move-down" ->
|
|
||||||
socket
|
|
||||||
|> State.update_state(&TreeOps.move_selected(&1, :down))
|
|
||||||
|> reload.(socket.assigns.workbench)
|
|
||||||
|
|
||||||
"indent" ->
|
|
||||||
socket
|
|
||||||
|> State.update_state(&TreeOps.indent_selected/1)
|
|
||||||
|> reload.(socket.assigns.workbench)
|
|
||||||
|
|
||||||
"unindent" ->
|
|
||||||
socket
|
|
||||||
|> State.update_state(&TreeOps.unindent_selected/1)
|
|
||||||
|> reload.(socket.assigns.workbench)
|
|
||||||
|
|
||||||
"delete" ->
|
|
||||||
socket
|
|
||||||
|> State.update_state(&TreeOps.delete_selected/1)
|
|
||||||
|> reload.(socket.assigns.workbench)
|
|
||||||
|
|
||||||
_other ->
|
|
||||||
reload.(socket, socket.assigns.workbench)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec drop_item(term(), term(), term(), term(), term()) :: term()
|
def handle_event(
|
||||||
def drop_item(socket, drag_item_id, target_item_id, position, reload) do
|
"menu_editor_drop_item",
|
||||||
|
%{
|
||||||
|
"drag_item_id" => drag_item_id,
|
||||||
|
"target_item_id" => target_item_id,
|
||||||
|
"position" => position
|
||||||
|
},
|
||||||
|
socket
|
||||||
|
) do
|
||||||
|
socket =
|
||||||
|
socket
|
||||||
|
|> State.update_state(&TreeOps.drop_selected(&1, drag_item_id, target_item_id, position))
|
||||||
|
|> build_data()
|
||||||
|
|
||||||
|
{:noreply, socket}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_event("menu_editor_keydown", %{"key" => "Escape"}, socket) do
|
||||||
|
socket =
|
||||||
|
socket
|
||||||
|
|> State.update_state(&DraftManagement.cancel_draft/1)
|
||||||
|
|> build_data()
|
||||||
|
|
||||||
|
{:noreply, socket}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_event("menu_editor_keydown", _params, socket) do
|
||||||
|
{:noreply, socket}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp handle_toolbar_action(socket, "add-entry") do
|
||||||
socket
|
socket
|
||||||
|> State.update_state(&TreeOps.drop_selected(&1, drag_item_id, target_item_id, position))
|
|> State.update_state(&DraftManagement.start_page_draft/1)
|
||||||
|> reload.(socket.assigns.workbench)
|
|> build_data()
|
||||||
end
|
end
|
||||||
|
|
||||||
@spec handle_keydown(term(), term(), term()) :: term()
|
defp handle_toolbar_action(socket, "add-category-archive") do
|
||||||
def handle_keydown(socket, "Escape", reload) do
|
socket
|
||||||
cancel_entry(socket, reload)
|
|> State.update_state(&DraftManagement.start_category_draft/1)
|
||||||
|
|> build_data()
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_keydown(socket, _key, reload) do
|
defp handle_toolbar_action(socket, "save") do
|
||||||
reload.(socket, socket.assigns.workbench)
|
do_save(socket)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp handle_toolbar_action(socket, "move-up") do
|
||||||
|
socket
|
||||||
|
|> State.update_state(&TreeOps.move_selected(&1, :up))
|
||||||
|
|> build_data()
|
||||||
|
end
|
||||||
|
|
||||||
|
defp handle_toolbar_action(socket, "move-down") do
|
||||||
|
socket
|
||||||
|
|> State.update_state(&TreeOps.move_selected(&1, :down))
|
||||||
|
|> build_data()
|
||||||
|
end
|
||||||
|
|
||||||
|
defp handle_toolbar_action(socket, "indent") do
|
||||||
|
socket
|
||||||
|
|> State.update_state(&TreeOps.indent_selected/1)
|
||||||
|
|> build_data()
|
||||||
|
end
|
||||||
|
|
||||||
|
defp handle_toolbar_action(socket, "unindent") do
|
||||||
|
socket
|
||||||
|
|> State.update_state(&TreeOps.unindent_selected/1)
|
||||||
|
|> build_data()
|
||||||
|
end
|
||||||
|
|
||||||
|
defp handle_toolbar_action(socket, "delete") do
|
||||||
|
socket
|
||||||
|
|> State.update_state(&TreeOps.delete_selected/1)
|
||||||
|
|> build_data()
|
||||||
|
end
|
||||||
|
|
||||||
|
defp handle_toolbar_action(socket, _other), do: socket
|
||||||
|
|
||||||
|
defp do_save(socket) do
|
||||||
|
state = socket.assigns.menu_editor_state
|
||||||
|
|
||||||
|
{:ok, _menu} =
|
||||||
|
BDS.Menu.update_menu(
|
||||||
|
state.project_id,
|
||||||
|
Enum.map(state.items, &TreeOps.persisted_item/1)
|
||||||
|
)
|
||||||
|
|
||||||
|
notify_output(translated("menuEditor.tabTitle"), translated("menuEditor.saved"), "info")
|
||||||
|
socket |> build_data()
|
||||||
|
end
|
||||||
|
|
||||||
|
defp ensure_project_assigns(socket) do
|
||||||
|
project_id = socket.assigns.project_id
|
||||||
|
|
||||||
|
if Map.has_key?(socket.assigns, :projects) do
|
||||||
|
socket
|
||||||
|
else
|
||||||
|
assign(socket, :projects, %{active_project_id: project_id})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp build_data(socket) do
|
||||||
|
tab_id = socket.assigns.current_tab.id
|
||||||
|
state = State.ensure_state(socket.assigns)
|
||||||
|
menu_editor = State.build(socket.assigns, state)
|
||||||
|
|
||||||
|
tab_meta =
|
||||||
|
Map.put(socket.assigns.tab_meta, {:menu_editor, tab_id}, %{
|
||||||
|
title: translated("menuEditor.tabTitle"),
|
||||||
|
subtitle: translated("menuEditor.description")
|
||||||
|
})
|
||||||
|
|
||||||
|
socket
|
||||||
|
|> assign(:menu_editor_state, state)
|
||||||
|
|> assign(:menu_editor, menu_editor)
|
||||||
|
|> assign(:tab_meta, tab_meta)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp notify_output(title, message, level) do
|
||||||
|
send(self(), {:menu_editor_output, title, message, level})
|
||||||
end
|
end
|
||||||
|
|
||||||
attr(:menu_editor, :map, required: true)
|
attr(:menu_editor, :map, required: true)
|
||||||
@@ -177,6 +258,7 @@ defmodule BDS.Desktop.ShellLive.MenuEditor do
|
|||||||
attr(:items, :list, required: true)
|
attr(:items, :list, required: true)
|
||||||
attr(:menu_editor, :map, required: true)
|
attr(:menu_editor, :map, required: true)
|
||||||
attr(:depth, :integer, required: true)
|
attr(:depth, :integer, required: true)
|
||||||
|
attr(:myself, :any, required: true)
|
||||||
|
|
||||||
@spec menu_tree_level(term()) :: term()
|
@spec menu_tree_level(term()) :: term()
|
||||||
def menu_tree_level(assigns) do
|
def menu_tree_level(assigns) do
|
||||||
@@ -199,6 +281,7 @@ defmodule BDS.Desktop.ShellLive.MenuEditor do
|
|||||||
data-selected={to_string(selected?)}
|
data-selected={to_string(selected?)}
|
||||||
phx-click={unless(editing?, do: "menu_editor_select_item")}
|
phx-click={unless(editing?, do: "menu_editor_select_item")}
|
||||||
phx-value-item_id={unless(editing?, do: item.item_id)}
|
phx-value-item_id={unless(editing?, do: item.item_id)}
|
||||||
|
phx-target={@myself}
|
||||||
style={"--menu-editor-depth: #{@depth};"}
|
style={"--menu-editor-depth: #{@depth};"}
|
||||||
>
|
>
|
||||||
<span class="menu-editor-row-handle" data-menu-drag-handle="true" title={translated("menuEditor.dragHandle")}>⋮⋮</span>
|
<span class="menu-editor-row-handle" data-menu-drag-handle="true" title={translated("menuEditor.dragHandle")}>⋮⋮</span>
|
||||||
@@ -213,6 +296,7 @@ defmodule BDS.Desktop.ShellLive.MenuEditor do
|
|||||||
data-testid="menu-editor-entry-form"
|
data-testid="menu-editor-entry-form"
|
||||||
phx-change="change_menu_editor_entry"
|
phx-change="change_menu_editor_entry"
|
||||||
phx-submit="submit_menu_editor_entry"
|
phx-submit="submit_menu_editor_entry"
|
||||||
|
phx-target={@myself}
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
class="menu-editor-inline-input"
|
class="menu-editor-inline-input"
|
||||||
@@ -241,7 +325,7 @@ defmodule BDS.Desktop.ShellLive.MenuEditor do
|
|||||||
</button>
|
</button>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<button class="menu-editor-inline-action" type="button" phx-click="cancel_menu_editor_entry">
|
<button class="menu-editor-inline-action" type="button" phx-click="cancel_menu_editor_entry" phx-target={@myself}>
|
||||||
<%= translated("Cancel") %>
|
<%= translated("Cancel") %>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -258,6 +342,7 @@ defmodule BDS.Desktop.ShellLive.MenuEditor do
|
|||||||
type="button"
|
type="button"
|
||||||
phx-click="select_menu_editor_page"
|
phx-click="select_menu_editor_page"
|
||||||
phx-value-post_id={post.id}
|
phx-value-post_id={post.id}
|
||||||
|
phx-target={@myself}
|
||||||
>
|
>
|
||||||
<span><%= post.title %></span>
|
<span><%= post.title %></span>
|
||||||
<small><%= post.slug %></small>
|
<small><%= post.slug %></small>
|
||||||
@@ -276,6 +361,7 @@ defmodule BDS.Desktop.ShellLive.MenuEditor do
|
|||||||
type="button"
|
type="button"
|
||||||
phx-click="select_menu_editor_category"
|
phx-click="select_menu_editor_category"
|
||||||
phx-value-name={category.name}
|
phx-value-name={category.name}
|
||||||
|
phx-target={@myself}
|
||||||
>
|
>
|
||||||
<span><%= category.title %></span>
|
<span><%= category.title %></span>
|
||||||
<small><%= category.name %></small>
|
<small><%= category.name %></small>
|
||||||
@@ -294,7 +380,7 @@ defmodule BDS.Desktop.ShellLive.MenuEditor do
|
|||||||
|
|
||||||
<%= if item.children != [] do %>
|
<%= if item.children != [] do %>
|
||||||
<ul class="menu-editor-tree-level">
|
<ul class="menu-editor-tree-level">
|
||||||
<.menu_tree_level items={item.children} menu_editor={@menu_editor} depth={@depth + 1} />
|
<.menu_tree_level items={item.children} menu_editor={@menu_editor} depth={@depth + 1} myself={@myself} />
|
||||||
</ul>
|
</ul>
|
||||||
<% end %>
|
<% end %>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<div class="menu-editor-view" data-testid="menu-editor" phx-window-keydown={if(@menu_editor.draft, do: "menu_editor_keydown")}>
|
<div class="menu-editor-view" data-testid="menu-editor" phx-window-keydown={if(@menu_editor.draft, do: "menu_editor_keydown")} phx-target={@myself}>
|
||||||
<div class="menu-editor-header">
|
<div class="menu-editor-header">
|
||||||
<div>
|
<div>
|
||||||
<h2><%= @menu_editor.title %></h2>
|
<h2><%= @menu_editor.title %></h2>
|
||||||
@@ -9,35 +9,35 @@
|
|||||||
<div class="menu-editor-main">
|
<div class="menu-editor-main">
|
||||||
<div class="menu-editor-tree-wrap">
|
<div class="menu-editor-tree-wrap">
|
||||||
<div class="menu-editor-toolbar" data-testid="menu-editor-toolbar" role="toolbar" aria-label={@menu_editor.title}>
|
<div class="menu-editor-toolbar" data-testid="menu-editor-toolbar" role="toolbar" aria-label={@menu_editor.title}>
|
||||||
<button class="menu-editor-tool" data-testid="menu-editor-toolbar-button" data-action="add-entry" type="button" phx-click="menu_editor_toolbar_action" phx-value-action="add-entry" title={translated("menuEditor.addEntry")}>
|
<button class="menu-editor-tool" data-testid="menu-editor-toolbar-button" data-action="add-entry" type="button" phx-click="menu_editor_toolbar_action" phx-value-action="add-entry" phx-target={@myself} title={translated("menuEditor.addEntry")}>
|
||||||
<svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor"><path d="M7 2h2v5h5v2H9v5H7V9H2V7h5V2z" /></svg>
|
<svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor"><path d="M7 2h2v5h5v2H9v5H7V9H2V7h5V2z" /></svg>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button class="menu-editor-tool" data-testid="menu-editor-toolbar-button" data-action="save" type="button" phx-click="menu_editor_toolbar_action" phx-value-action="save" title={translated("menuEditor.save")}>
|
<button class="menu-editor-tool" data-testid="menu-editor-toolbar-button" data-action="save" type="button" phx-click="menu_editor_toolbar_action" phx-value-action="save" phx-target={@myself} title={translated("menuEditor.save")}>
|
||||||
<svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor"><path d="M2 2h9l3 3v9H2V2zm2 1v3h6V3H4zm0 9h8V7H4v5z" /></svg>
|
<svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor"><path d="M2 2h9l3 3v9H2V2zm2 1v3h6V3H4zm0 9h8V7H4v5z" /></svg>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button class="menu-editor-tool" data-testid="menu-editor-toolbar-button" data-action="add-category-archive" type="button" phx-click="menu_editor_toolbar_action" phx-value-action="add-category-archive" title={translated("menuEditor.addCategoryArchive")}>
|
<button class="menu-editor-tool" data-testid="menu-editor-toolbar-button" data-action="add-category-archive" type="button" phx-click="menu_editor_toolbar_action" phx-value-action="add-category-archive" phx-target={@myself} title={translated("menuEditor.addCategoryArchive")}>
|
||||||
<span aria-hidden="true"><%= translated("menuEditor.addCategoryArchiveShort") %></span>
|
<span aria-hidden="true"><%= translated("menuEditor.addCategoryArchiveShort") %></span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button class="menu-editor-tool" data-testid="menu-editor-toolbar-button" data-action="move-up" type="button" phx-click="menu_editor_toolbar_action" phx-value-action="move-up" title={translated("menuEditor.moveUp")} disabled={not @menu_editor.can_move_up?}>
|
<button class="menu-editor-tool" data-testid="menu-editor-toolbar-button" data-action="move-up" type="button" phx-click="menu_editor_toolbar_action" phx-value-action="move-up" phx-target={@myself} title={translated("menuEditor.moveUp")} disabled={not @menu_editor.can_move_up?}>
|
||||||
<svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor"><path d="M8 3l4 4H9v6H7V7H4l4-4z" /></svg>
|
<svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor"><path d="M8 3l4 4H9v6H7V7H4l4-4z" /></svg>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button class="menu-editor-tool" data-testid="menu-editor-toolbar-button" data-action="move-down" type="button" phx-click="menu_editor_toolbar_action" phx-value-action="move-down" title={translated("menuEditor.moveDown")} disabled={not @menu_editor.can_move_down?}>
|
<button class="menu-editor-tool" data-testid="menu-editor-toolbar-button" data-action="move-down" type="button" phx-click="menu_editor_toolbar_action" phx-value-action="move-down" phx-target={@myself} title={translated("menuEditor.moveDown")} disabled={not @menu_editor.can_move_down?}>
|
||||||
<svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor"><path d="M7 3h2v6h3l-4 4-4-4h3V3z" /></svg>
|
<svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor"><path d="M7 3h2v6h3l-4 4-4-4h3V3z" /></svg>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button class="menu-editor-tool" data-testid="menu-editor-toolbar-button" data-action="indent" type="button" phx-click="menu_editor_toolbar_action" phx-value-action="indent" title={translated("menuEditor.indent")} disabled={not @menu_editor.can_indent?}>
|
<button class="menu-editor-tool" data-testid="menu-editor-toolbar-button" data-action="indent" type="button" phx-click="menu_editor_toolbar_action" phx-value-action="indent" phx-target={@myself} title={translated("menuEditor.indent")} disabled={not @menu_editor.can_indent?}>
|
||||||
<svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor"><path d="M2 4h8v2H2V4zm0 3h4v2H2V7zm0 3h8v2H2v-2zm6-1 3 2-3 2V9z" /></svg>
|
<svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor"><path d="M2 4h8v2H2V4zm0 3h4v2H2V7zm0 3h8v2H2v-2zm6-1 3 2-3 2V9z" /></svg>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button class="menu-editor-tool" data-testid="menu-editor-toolbar-button" data-action="unindent" type="button" phx-click="menu_editor_toolbar_action" phx-value-action="unindent" title={translated("menuEditor.unindent")} disabled={not @menu_editor.can_unindent?}>
|
<button class="menu-editor-tool" data-testid="menu-editor-toolbar-button" data-action="unindent" type="button" phx-click="menu_editor_toolbar_action" phx-value-action="unindent" phx-target={@myself} title={translated("menuEditor.unindent")} disabled={not @menu_editor.can_unindent?}>
|
||||||
<svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor"><path d="M2 4h8v2H2V4zm0 3h4v2H2V7zm0 3h8v2H2v-2zm3-1-3 2 3 2V9z" /></svg>
|
<svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor"><path d="M2 4h8v2H2V4zm0 3h4v2H2V7zm0 3h8v2H2v-2zm3-1-3 2 3 2V9z" /></svg>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button class="menu-editor-tool" data-testid="menu-editor-toolbar-button" data-action="delete" type="button" phx-click="menu_editor_toolbar_action" phx-value-action="delete" title={translated("menuEditor.delete")} disabled={not @menu_editor.can_delete?}>
|
<button class="menu-editor-tool" data-testid="menu-editor-toolbar-button" data-action="delete" type="button" phx-click="menu_editor_toolbar_action" phx-value-action="delete" phx-target={@myself} title={translated("menuEditor.delete")} disabled={not @menu_editor.can_delete?}>
|
||||||
<svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor"><path d="M6 2h4l1 1h3v2H2V3h3l1-1zm-1 4h2v6H5V6zm4 0h2v6H9V6z" /></svg>
|
<svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor"><path d="M6 2h4l1 1h3v2H2V3h3l1-1zm-1 4h2v6H5V6zm4 0h2v6H9V6z" /></svg>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -47,10 +47,10 @@
|
|||||||
<% else %>
|
<% else %>
|
||||||
<div id="menu-editor-tree-shell" class="menu-editor-tree-shell" phx-hook="MenuEditorTree">
|
<div id="menu-editor-tree-shell" class="menu-editor-tree-shell" phx-hook="MenuEditorTree">
|
||||||
<ul class="menu-editor-tree-level">
|
<ul class="menu-editor-tree-level">
|
||||||
<.menu_tree_level items={@menu_editor.items} menu_editor={@menu_editor} depth={0} />
|
<.menu_tree_level items={@menu_editor.items} menu_editor={@menu_editor} depth={0} myself={@myself} />
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -179,6 +179,13 @@ defmodule BDS.Desktop.ShellLive.TabHelpers do
|
|||||||
%{title: translated("Working tree"), subtitle: translated("Working tree and history")}
|
%{title: translated("Working tree"), subtitle: translated("Working tree and history")}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp derived_tab_meta(%{type: :menu_editor}) do
|
||||||
|
%{
|
||||||
|
title: translated("menuEditor.tabTitle"),
|
||||||
|
subtitle: translated("menuEditor.description")
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
defp derived_tab_meta(_tab), do: %{}
|
defp derived_tab_meta(_tab), do: %{}
|
||||||
|
|
||||||
defp merge_missing_meta(existing_meta, fresh_meta) do
|
defp merge_missing_meta(existing_meta, fresh_meta) do
|
||||||
|
|||||||
Reference in New Issue
Block a user