Refactored toggle liveview into a livecomponent
This commit is contained in:
parent
f22352da23
commit
771d2278d4
7 changed files with 73 additions and 27 deletions
|
|
@ -40,5 +40,9 @@ window.dispatchFor = (elementOrId, eventName, detail = {}) => {
|
||||||
const element =
|
const element =
|
||||||
typeof elementOrId === 'string' ? document.getElementById(elementOrId) : elementOrId
|
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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -42,9 +42,9 @@ defmodule PinchflatWeb.CustomComponents.TableComponents do
|
||||||
>
|
>
|
||||||
{col[:label]}
|
{col[:label]}
|
||||||
<.icon
|
<.icon
|
||||||
|
:if={to_string(@sort_key) == col[:sort_key]}
|
||||||
name={if @sort_direction == :asc, do: "hero-chevron-up", else: "hero-chevron-down"}
|
name={if @sort_direction == :asc, do: "hero-chevron-up", else: "hero-chevron-down"}
|
||||||
class="w-3 h-3 mt-2 ml-1 absolute"
|
class="w-3 h-3 mt-2 ml-1 absolute"
|
||||||
:if={to_string(@sort_key) == col[:sort_key]}
|
|
||||||
/>
|
/>
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
||||||
|
|
@ -81,8 +81,10 @@ defmodule PinchflatWeb.Sources.SourceLive.IndexTableLive do
|
||||||
from s in Source,
|
from s in Source,
|
||||||
as: :source,
|
as: :source,
|
||||||
inner_join: mp in assoc(s, :media_profile),
|
inner_join: mp in assoc(s, :media_profile),
|
||||||
left_join: d in subquery(downloaded_subquery), on: d.source_id == s.id,
|
left_join: d in subquery(downloaded_subquery),
|
||||||
left_join: p in subquery(pending_subquery), on: p.source_id == s.id,
|
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,
|
on: d.source_id == s.id,
|
||||||
where: is_nil(s.marked_for_deletion_at) and is_nil(mp.marked_for_deletion_at),
|
where: is_nil(s.marked_for_deletion_at) and is_nil(mp.marked_for_deletion_at),
|
||||||
preload: [media_profile: mp],
|
preload: [media_profile: mp],
|
||||||
|
|
|
||||||
|
|
@ -14,4 +14,27 @@
|
||||||
<.localized_number number={source.downloaded_count} />
|
<.localized_number number={source.downloaded_count} />
|
||||||
</.subtle_link>
|
</.subtle_link>
|
||||||
</:col>
|
</:col>
|
||||||
|
<: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 %>
|
||||||
|
<span class="text-lg">∞</span>
|
||||||
|
<% end %>
|
||||||
|
</:col>
|
||||||
|
<:col :let={source} label="Media Profile">
|
||||||
|
<.subtle_link href={~p"/media_profiles/#{source.media_profile_id}"}>
|
||||||
|
{source.media_profile.name}
|
||||||
|
</.subtle_link>
|
||||||
|
</:col>
|
||||||
|
<:col :let={source} label="Enabled?">
|
||||||
|
<.live_component
|
||||||
|
module={PinchflatWeb.Sources.SourceLive.SourceEnableToggle}
|
||||||
|
source={source}
|
||||||
|
id={"source_#{source.id}_enabled"}
|
||||||
|
/>
|
||||||
|
</:col>
|
||||||
|
<:col :let={source} label="" class="flex place-content-evenly">
|
||||||
|
<.icon_link href={~p"/sources/#{source.id}/edit"} icon="hero-pencil-square" class="mx-1" />
|
||||||
|
</:col>
|
||||||
</.table>
|
</.table>
|
||||||
|
|
|
||||||
|
|
@ -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"""
|
||||||
|
<div>
|
||||||
|
<.form :let={f} for={@form} phx-change="update" phx-target={@myself}>
|
||||||
|
<.input
|
||||||
|
id={"source_#{@source_id}_enabled_input"}
|
||||||
|
field={f[:enabled]}
|
||||||
|
type="toggle"
|
||||||
|
/>
|
||||||
|
</.form>
|
||||||
|
</div>
|
||||||
|
"""
|
||||||
|
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
|
||||||
|
|
@ -47,6 +47,7 @@ defmodule PinchflatWeb.Sources.IndexTableLiveTest do
|
||||||
}
|
}
|
||||||
|
|
||||||
# Send an event to the server directly
|
# Send an event to the server directly
|
||||||
|
# TODO: remove
|
||||||
render_change(view, "formless-input", params)
|
render_change(view, "formless-input", params)
|
||||||
|
|
||||||
assert %{enabled: false} = Repo.get!(Source, source.id)
|
assert %{enabled: false} = Repo.get!(Source, source.id)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue