Skip to content

Commit

Permalink
Use IDs for LiveData (#141)
Browse files Browse the repository at this point in the history
* Use IDs for LiveData

---------

Co-authored-by: Leandro Pereira <[email protected]>
  • Loading branch information
APB9785 and leandrocp authored May 6, 2024
1 parent b943de5 commit 95ef14e
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 113 deletions.
16 changes: 4 additions & 12 deletions lib/beacon/live_admin/content.ex
Original file line number Diff line number Diff line change
Expand Up @@ -210,20 +210,12 @@ defmodule Beacon.LiveAdmin.Content do
call(site, Beacon.Content, :create_assign_for_live_data, [live_data, attrs])
end

def get_live_data(site, path) do
call(site, Beacon.Content, :get_live_data, [site, path])
def get_live_data(site, id) do
call(site, Beacon.Content, :get_live_data, [id])
end

def live_data_for_site(site) do
call(site, Beacon.Content, :live_data_for_site, [site])
end

def live_data_paths_for_site(site) do
call(site, Beacon.Content, :live_data_paths_for_site, [site])
end

def live_data_paths_for_site(site, opts) do
call(site, Beacon.Content, :live_data_paths_for_site, [site, opts])
def live_data_for_site(site, opts \\ []) do
call(site, Beacon.Content, :live_data_for_site, [site, opts])
end

def update_live_data_path(site, live_data, attrs) do
Expand Down
50 changes: 24 additions & 26 deletions lib/beacon/live_admin/live/live_data_editor_live/assigns.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,29 @@ defmodule Beacon.LiveAdmin.LiveDataEditorLive.Assigns do
def menu_link(_, _), do: :skip

def handle_params(params, _url, socket) do
path = URI.decode_www_form(params["path"])
%{beacon_page: %{site: site}} = socket.assigns

socket =
socket
|> assign(live_data: Content.get_live_data(socket.assigns.beacon_page.site, path))
|> assign(live_data: Content.get_live_data(site, params["live_data_id"]))
|> assign(unsaved_changes: false)
|> assign(show_nav_modal: false)
|> assign(show_create_modal: false)
|> assign(show_delete_modal: false)
|> assign(new_assign_form: to_form(%{"key" => ""}))
|> assign(page_title: "Live Data")
|> assign_selected(params["key"])
|> assign_selected(params["assign_id"])
|> assign_form()

{:noreply, socket}
end

def handle_event("select-" <> key, _, socket) do
%{live_data: %{site: site, path: path}} = socket.assigns
def handle_event("select-" <> assign_id, _, socket) do
%{live_data: %{site: site} = live_data, unsaved_changes: unsaved_changes} = socket.assigns

path =
beacon_live_admin_path(
socket,
site,
"/live_data/#{sanitize(path)}/#{sanitize(key)}"
)
path = beacon_live_admin_path(socket, site, "/live_data/#{live_data.id}/assigns/#{assign_id}")

if socket.assigns.unsaved_changes do
if unsaved_changes do
{:noreply, assign(socket, show_nav_modal: true, confirm_nav_path: path)}
else
{:noreply, push_redirect(socket, to: path)}
Expand Down Expand Up @@ -94,7 +89,7 @@ defmodule Beacon.LiveAdmin.LiveDataEditorLive.Assigns do
end

def handle_event("save_changes", %{"live_data_assign" => params}, socket) do
%{selected: selected, live_data: %{site: site, path: live_data_path}} = socket.assigns
%{selected: selected, live_data: %{site: site} = live_data} = socket.assigns

attrs = %{key: params["key"], value: params["value"], format: params["format"]}

Expand All @@ -105,11 +100,11 @@ defmodule Beacon.LiveAdmin.LiveDataEditorLive.Assigns do
beacon_live_admin_path(
socket,
site,
"/live_data/#{sanitize(live_data_path)}/#{sanitize(live_data_assign.key)}"
"/live_data/#{live_data.id}/assigns/#{live_data_assign.id}"
)

socket
|> assign(live_data: Content.get_live_data(site, live_data_path))
|> assign(live_data: Content.get_live_data(site, live_data.id))
|> assign_form()
|> assign(unsaved_changes: false)
|> push_patch(to: path)
Expand All @@ -128,7 +123,7 @@ defmodule Beacon.LiveAdmin.LiveDataEditorLive.Assigns do

def handle_event("submit_new", params, socket) do
%{live_data: %{site: site} = live_data, selected: selected} = socket.assigns
selected = selected || %{key: nil}
selected = selected || %{id: nil}

attrs = %{key: params["key"], value: "Your value here", format: :text}
# TODO: handle errors
Expand All @@ -137,7 +132,7 @@ defmodule Beacon.LiveAdmin.LiveDataEditorLive.Assigns do
socket =
socket
|> assign(live_data: updated_live_data)
|> assign_selected(selected.key)
|> assign_selected(selected.id)

{:noreply, assign(socket, show_create_modal: false)}
end
Expand All @@ -147,13 +142,13 @@ defmodule Beacon.LiveAdmin.LiveDataEditorLive.Assigns do
end

def handle_event("delete_confirm", _, socket) do
%{selected: selected, live_data: %{site: site, path: path}} = socket.assigns
%{selected: selected, live_data: %{site: site} = live_data} = socket.assigns

{:ok, _} = Content.delete_live_data_assign(site, selected)

{:noreply,
push_redirect(socket,
to: beacon_live_admin_path(socket, site, "/live_data/#{sanitize(path)}")
to: beacon_live_admin_path(socket, site, "/live_data/#{live_data.id}/assigns")
)}
end

Expand Down Expand Up @@ -223,7 +218,7 @@ defmodule Beacon.LiveAdmin.LiveDataEditorLive.Assigns do
<div>Path:</div>
<div><%= @live_data.path %></div>
</div>
<.table :if={@selected} id="assigns" rows={@live_data.assigns} row_click={fn assign -> "select-#{assign.key}" end}>
<.table :if={@selected} id="assigns" rows={@live_data.assigns} row_click={fn assign -> "select-#{assign.id}" end}>
<:col :let={assign} label="assign">
@<%= assign.key %>
</:col>
Expand Down Expand Up @@ -272,14 +267,19 @@ defmodule Beacon.LiveAdmin.LiveDataEditorLive.Assigns do
end
end

defp assign_selected(socket, key) do
key = URI.decode_www_form(key)
selected = Enum.find(socket.assigns.live_data.assigns, &(&1.key == key))
defp assign_selected(socket, id) do
%{live_data: live_data} = socket.assigns
selected = Enum.find(live_data.assigns, &(&1.id == id))

if selected do
assign(socket, selected: selected, changed_value: selected.value)
else
path = beacon_live_admin_path(socket, socket.assigns.beacon_page.site, "/live_data")
path =
beacon_live_admin_path(
socket,
socket.assigns.beacon_page.site,
"/live_data/#{live_data.id}/assigns"
)

socket
|> assign(selected: nil)
Expand All @@ -306,8 +306,6 @@ defmodule Beacon.LiveAdmin.LiveDataEditorLive.Assigns do
assign(socket, :form, to_form(changeset))
end

defp sanitize(path_or_key), do: URI.encode_www_form(path_or_key)

defp variables_available(path) do
path
|> String.split("/", trim: true)
Expand Down
43 changes: 14 additions & 29 deletions lib/beacon/live_admin/live/live_data_editor_live/index.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,22 @@ defmodule Beacon.LiveAdmin.LiveDataEditorLive.Index do

def handle_params(%{"query" => query}, _uri, socket) do
%{beacon_page: %{site: site}} = socket.assigns
live_data_paths = Content.live_data_paths_for_site(site, query: query)
live_data_paths = Content.live_data_for_site(site, query: query)

{:noreply, assign(socket, live_data_paths: live_data_paths)}
{:noreply, assign(socket, live_data_list: live_data_paths)}
end

def handle_params(params, _uri, socket) do
%{beacon_page: %{site: site}, live_action: live_action} = socket.assigns

socket =
socket
|> assign(live_data_paths: Content.live_data_paths_for_site(site))
|> assign(live_data_list: Content.live_data_for_site(site))
|> assign(show_new_path_modal: live_action == :new)
|> assign(show_edit_path_modal: live_action == :edit)
|> assign(show_delete_path_modal: live_action == :delete)
|> assign_edit_path_form(params["path"])
|> assign_selected(params["path"])
|> assign_edit_path_form(params["live_data_id"])
|> assign_selected(params["live_data_id"])

{:noreply, socket}
end
Expand All @@ -50,10 +50,9 @@ defmodule Beacon.LiveAdmin.LiveDataEditorLive.Index do
case Content.create_live_data(site, %{path: path, site: site}) do
{:ok, live_data} ->
socket
|> assign(live_data_paths: Content.live_data_paths_for_site(site))
|> assign(live_data_list: Content.live_data_for_site(site))
|> push_navigate(
to:
beacon_live_admin_path(socket, site, "/live_data/#{sanitize_path(live_data.path)}")
to: beacon_live_admin_path(socket, site, "/live_data/#{live_data.id}/assigns")
)

{:error, _changeset} ->
Expand All @@ -65,7 +64,7 @@ defmodule Beacon.LiveAdmin.LiveDataEditorLive.Index do

def handle_event("edit_path", params, socket) do
%{beacon_page: %{site: site}, selected: selected} = socket.assigns
%{"live_data" => %{"path" => path}} = params
%{"path" => path} = params

{:ok, _live_data} = Content.update_live_data_path(site, selected, path)

Expand All @@ -87,17 +86,7 @@ defmodule Beacon.LiveAdmin.LiveDataEditorLive.Index do
{:noreply, push_navigate(socket, to: path, replace: true)}
end

defp assign_edit_path_form(socket, nil), do: assign(socket, edit_path_form: to_form(%{}))

defp assign_edit_path_form(socket, path) do
form =
{%{}, %{path: :string}}
|> Ecto.Changeset.cast(%{path: path}, [:path])
|> Ecto.Changeset.validate_required([:path])
|> to_form(as: :live_data)

assign(socket, edit_path_form: form)
end
defp assign_edit_path_form(socket, _id), do: assign(socket, edit_path_form: to_form(%{}))

defp assign_selected(socket, nil), do: assign(socket, selected: nil)

Expand Down Expand Up @@ -126,16 +115,16 @@ defmodule Beacon.LiveAdmin.LiveDataEditorLive.Index do
</.simple_form>
<.main_content>
<.table id="live_data" rows={@live_data_paths} row_click={fn live_data_path -> JS.navigate(beacon_live_admin_path(@socket, @beacon_page.site, "/live_data/#{sanitize_path(live_data_path)}")) end}>
<:col :let={live_data_path} label="Path"><%= live_data_path %></:col>
<:action :let={live_data_path}>
<.table id="live_data" rows={@live_data_list} row_click={&JS.navigate(beacon_live_admin_path(@socket, @beacon_page.site, "/live_data/#{&1.id}/assigns"))} row_id={&"live-data-table-row-#{&1.id}"}>
<:col :let={live_data} label="Path"><%= live_data.path %></:col>
<:action :let={live_data}>
<div class="sr-only">
<.link id={"edit-live-data-" <> live_data_path} navigate={beacon_live_admin_path(@socket, @beacon_page.site, "/live_data/edit/#{sanitize_path(live_data_path)}")} title="Edit live data">
<.link id={"edit-live-data-" <> live_data.id} navigate={beacon_live_admin_path(@socket, @beacon_page.site, "/live_data/#{live_data.id}")} title="Edit live data">
Edit
</.link>
</div>
<.link
patch={beacon_live_admin_path(@socket, @beacon_page.site, "/live_data/edit/#{sanitize_path(live_data_path)}")}
patch={beacon_live_admin_path(@socket, @beacon_page.site, "/live_data/#{live_data.id}")}
title="Edit live data"
aria-label="Edit live data"
class="flex items-center justify-center w-10 h-10 group"
Expand Down Expand Up @@ -170,8 +159,4 @@ defmodule Beacon.LiveAdmin.LiveDataEditorLive.Index do
</.modal>
"""
end

defp sanitize_path(path) do
URI.encode_www_form(path)
end
end
8 changes: 5 additions & 3 deletions lib/beacon/live_admin/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,11 @@ defmodule Beacon.LiveAdmin.Router do
# live data
{"/live_data", Beacon.LiveAdmin.LiveDataEditorLive.Index, :index, %{}},
{"/live_data/new", Beacon.LiveAdmin.LiveDataEditorLive.Index, :new, %{}},
{"/live_data/edit/:path", Beacon.LiveAdmin.LiveDataEditorLive.Index, :edit, %{}},
{"/live_data/:path", Beacon.LiveAdmin.LiveDataEditorLive.Assigns, :assigns, %{}},
{"/live_data/:path/:key", Beacon.LiveAdmin.LiveDataEditorLive.Assigns, :assigns, %{}},
{"/live_data/:live_data_id", Beacon.LiveAdmin.LiveDataEditorLive.Index, :edit, %{}},
{"/live_data/:live_data_id/assigns", Beacon.LiveAdmin.LiveDataEditorLive.Assigns, :assigns,
%{}},
{"/live_data/:live_data_id/assigns/:assign_id", Beacon.LiveAdmin.LiveDataEditorLive.Assigns,
:assigns, %{}},
# media library
{"/media_library", Beacon.LiveAdmin.MediaLibraryLive.Index, :index, %{}},
{"/media_library/upload", Beacon.LiveAdmin.MediaLibraryLive.Index, :upload, %{}},
Expand Down
4 changes: 2 additions & 2 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
%{
"accent": {:hex, :accent, "1.1.1", "20257356446d45078b19b91608f74669b407b39af891ee3db9ee6824d1cae19d", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:plug, "~> 1.3", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "6d5afa50d4886e3370e04fa501468cbaa6c4b5fe926f72ccfa844ad9e259adae"},
"beacon": {:git, "https://github.com/beaconCMS/beacon.git", "963491986df5988a180e6fa81f705f25428dd377", []},
"castore": {:hex, :castore, "1.0.7", "b651241514e5f6956028147fe6637f7ac13802537e895a724f90bf3e36ddd1dd", [:mix], [], "hexpm", "da7785a4b0d2a021cd1292a60875a784b6caef71e76bf4917bdee1f390455cf5"},
"beacon": {:git, "https://github.com/beaconCMS/beacon.git", "0a2260e15ba57fd867489d85254671db74a0d442", []},
"castore": {:hex, :castore, "1.0.5", "9eeebb394cc9a0f3ae56b813459f990abb0a3dedee1be6b27fdb50301930502f", [:mix], [], "hexpm", "8d7c597c3e4a64c395980882d4bca3cebb8d74197c590dc272cfd3b6a6310578"},
"cc_precompiler": {:hex, :cc_precompiler, "0.1.9", "e8d3364f310da6ce6463c3dd20cf90ae7bbecbf6c5203b98bf9b48035592649b", [:mix], [{:elixir_make, "~> 0.7", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "9dcab3d0f3038621f1601f13539e7a9ee99843862e66ad62827b0c42b2f58a54"},
"cowboy": {:hex, :cowboy, "2.12.0", "f276d521a1ff88b2b9b4c54d0e753da6c66dd7be6c9fca3d9418b561828a3731", [:make, :rebar3], [{:cowlib, "2.13.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "8a7abe6d183372ceb21caa2709bec928ab2b72e18a3911aa1771639bef82651e"},
"cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"},
Expand Down
35 changes: 18 additions & 17 deletions test/beacon/live_admin/live/live_data_editor_live/assigns_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ defmodule Beacon.LiveAdmin.LiveDataEditorLive.AssignsTest do
rpc(node1(), Beacon.Repo, :delete_all, [Beacon.Content.LiveDataAssign, [log: false]])
end)

page_fixture()
page = page_fixture()
live_data = live_data_fixture(node1(), path: "/home")

[live_data: live_data]
[page: page, live_data: live_data]
end

test "create new assign", %{conn: conn} do
{:ok, view, _html} = live(conn, "/admin/site_a/live_data/%2Fhome")
test "create new assign", %{conn: conn, live_data: live_data} do
{:ok, view, _html} = live(conn, "/admin/site_a/live_data/#{live_data.id}/assigns")

view
|> element("button", "New Live Data Assign")
Expand All @@ -27,28 +27,29 @@ defmodule Beacon.LiveAdmin.LiveDataEditorLive.AssignsTest do
|> form("#new-assign-form", %{"key" => "valid?"})
|> render_submit()

{:ok, view, html} = live(conn, "/admin/site_a/live_data/%2Fhome/valid%3F")
assert render(view) =~ "@valid?"
end

assert html =~ "@valid?"
assert has_element?(view, ~S|input[value="valid?"]|)
test "nonexistent assign redirects to root live data page", %{conn: conn, live_data: live_data} do
assert {:error, {:live_redirect, %{to: "/admin/site_a/live_data/#{live_data.id}/assigns"}}} ==
live(conn, "/admin/site_a/live_data/#{live_data.id}/assigns/invalid-id")
end

test "edit existing assign", %{conn: conn, live_data: live_data} do
live_data_assign_fixture(node1(), live_data: live_data)
{:ok, view, _html} = live(conn, "/admin/site_a/live_data/%2Fhome/sum")
lda = live_data_assign_fixture(node1(), live_data: live_data)
{:ok, view, _html} = live(conn, "/admin/site_a/live_data/#{live_data.id}/assigns/#{lda.id}")

html =
view
|> form("#edit-assign-form", %{"live_data_assign" => %{"key" => "new_key"}})
|> render_submit()
view
|> form("#edit-assign-form", %{"live_data_assign" => %{"key" => "new_key"}})
|> render_submit()

assert html =~ "@new_key"
assert render(view) =~ "@new_key"
assert has_element?(view, ~S|input[value="new_key"]|)
end

test "delete existing assign", %{conn: conn, live_data: live_data} do
live_data_assign_fixture(node1(), live_data: live_data)
{:ok, view, _html} = live(conn, "/admin/site_a/live_data/%2Fhome/sum")
lda = live_data_assign_fixture(node1(), live_data: live_data)
{:ok, view, _html} = live(conn, "/admin/site_a/live_data/#{live_data.id}/assigns/#{lda.id}")

view
|> element("button", "Delete")
Expand All @@ -60,6 +61,6 @@ defmodule Beacon.LiveAdmin.LiveDataEditorLive.AssignsTest do
|> render_click()
|> follow_redirect(conn)

refute html =~ "@sum"
refute html =~ "@#{lda.key}"
end
end
Loading

0 comments on commit 95ef14e

Please sign in to comment.