diff --git a/assets/js/alpine_helpers.js b/assets/js/alpine_helpers.js index 2d8bd93..9c2367f 100644 --- a/assets/js/alpine_helpers.js +++ b/assets/js/alpine_helpers.js @@ -40,5 +40,9 @@ window.dispatchFor = (elementOrId, eventName, detail = {}) => { const element = typeof elementOrId === 'string' ? document.getElementById(elementOrId) : elementOrId - element.dispatchEvent(new CustomEvent(eventName, { detail })) + // This is needed to ensure the DOM has updated before dispatching the event. + // Doing so ensures that the latest DOM state is what's sent to the server + setTimeout(() => { + element.dispatchEvent(new Event(eventName, { bubbles: true, detail })) + }, 0) } diff --git a/assets/js/app.js b/assets/js/app.js index f9accf3..e6e0219 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -47,29 +47,6 @@ let liveSocket = new LiveSocket(document.body.dataset.socketPath, Socket, { } }) } - }, - 'formless-input': { - mounted() { - const subscribedEvents = this.el.dataset.subscribe.split(' ') - const eventName = this.el.dataset.eventName || '' - const identifier = this.el.dataset.identifier || '' - - subscribedEvents.forEach((domEvent) => { - this.el.addEventListener(domEvent, () => { - // This ensures that the event is pushed to the server after the input value has been updated - // so that the server has the most up-to-date value - setTimeout(() => { - this.pushEvent('formless-input', { - value: this.el.value, - id: identifier, - event: eventName, - dom_id: this.el.id, - dom_event: domEvent - }) - }, 0) - }) - }) - } } } }) diff --git a/lib/pinchflat_web/components/custom_components/table_components.ex b/lib/pinchflat_web/components/custom_components/table_components.ex index 2d714a7..1fad86e 100644 --- a/lib/pinchflat_web/components/custom_components/table_components.ex +++ b/lib/pinchflat_web/components/custom_components/table_components.ex @@ -42,9 +42,9 @@ defmodule PinchflatWeb.CustomComponents.TableComponents do > {col[:label]} <.icon + :if={to_string(@sort_key) == col[:sort_key]} name={if @sort_direction == :asc, do: "hero-chevron-up", else: "hero-chevron-down"} class="w-3 h-3 mt-2 ml-1 absolute" - :if={to_string(@sort_key) == col[:sort_key]} /> diff --git a/lib/pinchflat_web/controllers/sources/source_live/index_table_live.ex b/lib/pinchflat_web/controllers/sources/source_live/index_table_live.ex index d95a950..8125d2a 100644 --- a/lib/pinchflat_web/controllers/sources/source_live/index_table_live.ex +++ b/lib/pinchflat_web/controllers/sources/source_live/index_table_live.ex @@ -81,8 +81,10 @@ defmodule PinchflatWeb.Sources.SourceLive.IndexTableLive do from s in Source, as: :source, inner_join: mp in assoc(s, :media_profile), - left_join: d in subquery(downloaded_subquery), on: d.source_id == s.id, - left_join: p in subquery(pending_subquery), on: p.source_id == s.id, + left_join: d in subquery(downloaded_subquery), + on: d.source_id == s.id, + left_join: p in subquery(pending_subquery), + on: p.source_id == s.id, on: d.source_id == s.id, where: is_nil(s.marked_for_deletion_at) and is_nil(mp.marked_for_deletion_at), preload: [media_profile: mp], diff --git a/lib/pinchflat_web/controllers/sources/source_live/index_table_live.html.heex b/lib/pinchflat_web/controllers/sources/source_live/index_table_live.html.heex index d4eceeb..76c7231 100644 --- a/lib/pinchflat_web/controllers/sources/source_live/index_table_live.html.heex +++ b/lib/pinchflat_web/controllers/sources/source_live/index_table_live.html.heex @@ -14,4 +14,27 @@ <.localized_number number={source.downloaded_count} /> + <:col :let={source} label="Retention"> + <%= if source.retention_period_days && source.retention_period_days > 0 do %> + <.localized_number number={source.retention_period_days} /> + <.pluralize count={source.retention_period_days} word="day" /> + <% else %> + + <% end %> + + <:col :let={source} label="Media Profile"> + <.subtle_link href={~p"/media_profiles/#{source.media_profile_id}"}> + {source.media_profile.name} + + + <:col :let={source} label="Enabled?"> + <.live_component + module={PinchflatWeb.Sources.SourceLive.SourceEnableToggle} + source={source} + id={"source_#{source.id}_enabled"} + /> + + <:col :let={source} label="" class="flex place-content-evenly"> + <.icon_link href={~p"/sources/#{source.id}/edit"} icon="hero-pencil-square" class="mx-1" /> + diff --git a/lib/pinchflat_web/controllers/sources/source_live/source_enable_toggle.ex b/lib/pinchflat_web/controllers/sources/source_live/source_enable_toggle.ex new file mode 100644 index 0000000..c0f4b65 --- /dev/null +++ b/lib/pinchflat_web/controllers/sources/source_live/source_enable_toggle.ex @@ -0,0 +1,39 @@ +defmodule PinchflatWeb.Sources.SourceLive.SourceEnableToggle do + use PinchflatWeb, :live_component + + alias Pinchflat.Sources + alias Pinchflat.Sources.Source + + def render(assigns) do + ~H""" +
+ <.form :let={f} for={@form} phx-change="update" phx-target={@myself}> + <.input + id={"source_#{@source_id}_enabled_input"} + field={f[:enabled]} + type="toggle" + /> + +
+ """ + end + + def update(assigns, socket) do + initial_data = %{ + source_id: assigns.source.id, + form: Sources.change_source(%Source{}, assigns.source) + } + + socket + |> assign(initial_data) + |> then(&{:ok, &1}) + end + + def handle_event("update", %{"source" => source_params}, %{assigns: assigns} = socket) do + assigns.source_id + |> Sources.get_source!() + |> Sources.update_source(source_params) + + {:noreply, socket} + end +end diff --git a/test/pinchflat_web/controllers/sources/index_table_live_test.exs b/test/pinchflat_web/controllers/sources/index_table_live_test.exs index 659bd04..23509ef 100644 --- a/test/pinchflat_web/controllers/sources/index_table_live_test.exs +++ b/test/pinchflat_web/controllers/sources/index_table_live_test.exs @@ -47,6 +47,7 @@ defmodule PinchflatWeb.Sources.IndexTableLiveTest do } # Send an event to the server directly + # TODO: remove render_change(view, "formless-input", params) assert %{enabled: false} = Repo.get!(Source, source.id)