Updated toggle component and moved MP index table to a liveview
This commit is contained in:
parent
2d4b86de71
commit
e893b71e20
7 changed files with 124 additions and 19 deletions
|
|
@ -35,3 +35,10 @@ window.markVersionAsSeen = (versionString) => {
|
|||
window.isVersionSeen = (versionString) => {
|
||||
return localStorage.getItem('seenVersion') === versionString
|
||||
}
|
||||
|
||||
window.dispatchFor = (elementOrId, eventName, detail = {}) => {
|
||||
const element =
|
||||
typeof elementOrId === 'string' ? document.getElementById(elementOrId) : elementOrId
|
||||
|
||||
element.dispatchEvent(new CustomEvent(eventName, { detail }))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ let liveSocket = new LiveSocket(document.body.dataset.socketPath, Socket, {
|
|||
}
|
||||
},
|
||||
hooks: {
|
||||
supressEnterSubmission: {
|
||||
'supress-enter-submission': {
|
||||
mounted() {
|
||||
this.el.addEventListener('keypress', (event) => {
|
||||
if (event.key === 'Enter') {
|
||||
|
|
@ -47,6 +47,29 @@ 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)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
|||
29
lib/pinchflat/profiles/profiles_query.ex
Normal file
29
lib/pinchflat/profiles/profiles_query.ex
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
defmodule Pinchflat.Profiles.ProfilesQuery do
|
||||
@moduledoc """
|
||||
Query helpers for the Profiles context.
|
||||
|
||||
These methods are made to be one-ish liners used
|
||||
to compose queries. Each method should strive to do
|
||||
_one_ thing. These don't need to be tested as
|
||||
they are just building blocks for other functionality
|
||||
which, itself, will be tested.
|
||||
"""
|
||||
import Ecto.Query, warn: false
|
||||
|
||||
alias Pinchflat.Profiles.MediaProfile
|
||||
|
||||
# This allows the module to be aliased and query methods to be used
|
||||
# all in one go
|
||||
# usage: use Pinchflat.Profiles.ProfilesQuery
|
||||
defmacro __using__(_opts) do
|
||||
quote do
|
||||
import Ecto.Query, warn: false
|
||||
|
||||
alias unquote(__MODULE__)
|
||||
end
|
||||
end
|
||||
|
||||
def new do
|
||||
MediaProfile
|
||||
end
|
||||
end
|
||||
|
|
@ -340,14 +340,15 @@ defmodule PinchflatWeb.CoreComponents do
|
|||
end)
|
||||
|
||||
~H"""
|
||||
<div x-data={"{ enabled: #{@checked}}"}>
|
||||
<.label for={@id}>
|
||||
<div x-data={"{ enabled: #{@checked}}"} class="">
|
||||
<.label :if={@label} for={@id}>
|
||||
<%= @label %>
|
||||
<span :if={@label_suffix} class="text-xs text-bodydark"><%= @label_suffix %></span>
|
||||
</.label>
|
||||
<div class="relative">
|
||||
<div class="relative flex flex-col">
|
||||
<input type="hidden" id={@id} name={@name} x-bind:value="enabled" {@rest} />
|
||||
<div class="inline-block cursor-pointer" @click="enabled = !enabled">
|
||||
<%!-- This triggers a `change` event on the hidden input when the toggle is clicked --%>
|
||||
<div class="inline-block cursor-pointer" @click={"enabled = !enabled; dispatchFor('#{@id}', 'change')"}>
|
||||
<div x-bind:class="enabled && '!bg-primary'" class="block h-8 w-14 rounded-full bg-black"></div>
|
||||
<div
|
||||
x-bind:class="enabled && '!right-1 !translate-x-full'"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ defmodule Pinchflat.UpgradeButtonLive do
|
|||
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<form id="upgradeForm" phx-change="check_matching_text" phx-hook="supressEnterSubmission">
|
||||
<form id="upgradeForm" phx-change="check_matching_text" phx-hook="supress-enter-submission">
|
||||
<.input type="text" name="unlock-pro-textbox" value="" />
|
||||
</form>
|
||||
|
||||
|
|
|
|||
|
|
@ -14,19 +14,7 @@
|
|||
<div class="rounded-sm border border-stroke bg-white shadow-default dark:border-strokedark dark:bg-boxdark">
|
||||
<div class="max-w-full overflow-x-auto">
|
||||
<div class="flex flex-col gap-10 min-w-max">
|
||||
<.table rows={@media_profiles} table_class="text-black dark:text-white">
|
||||
<:col :let={media_profile} label="Name">
|
||||
<.subtle_link href={~p"/media_profiles/#{media_profile.id}"}>
|
||||
<%= media_profile.name %>
|
||||
</.subtle_link>
|
||||
</:col>
|
||||
<:col :let={media_profile} label="Preferred Resolution">
|
||||
<%= media_profile.preferred_resolution %>
|
||||
</:col>
|
||||
<:col :let={media_profile} label="" class="flex justify-end">
|
||||
<.icon_link href={~p"/media_profiles/#{media_profile.id}/edit"} icon="hero-pencil-square" class="mr-4" />
|
||||
</:col>
|
||||
</.table>
|
||||
<%= live_render(@conn, PinchflatWeb.MediaProfiles.IndexTableLive) %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
defmodule PinchflatWeb.MediaProfiles.IndexTableLive do
|
||||
use PinchflatWeb, :live_view
|
||||
use Pinchflat.Profiles.ProfilesQuery
|
||||
|
||||
alias Pinchflat.Repo
|
||||
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<.table rows={@media_profiles} table_class="text-black dark:text-white">
|
||||
<:col :let={media_profile} label="Name">
|
||||
<.subtle_link href={~p"/media_profiles/#{media_profile.id}"}>
|
||||
<%= media_profile.name %>
|
||||
</.subtle_link>
|
||||
</:col>
|
||||
<:col :let={media_profile} label="Preferred Resolution">
|
||||
<%= media_profile.preferred_resolution %>
|
||||
</:col>
|
||||
<:col :let={media_profile} label="Enabled?">
|
||||
<.input
|
||||
name={"media_profile[#{media_profile.id}][enabled]"}
|
||||
id={"media_profile_#{media_profile.id}_enabled"}
|
||||
phx-hook="formless-input"
|
||||
data-subscribe="change"
|
||||
data-event-name="toggle_enabled"
|
||||
data-identifier={media_profile.id}
|
||||
type="toggle"
|
||||
/>
|
||||
</:col>
|
||||
<:col :let={media_profile} label="" class="flex justify-end">
|
||||
<.icon_link href={~p"/media_profiles/#{media_profile.id}/edit"} icon="hero-pencil-square" class="mr-4" />
|
||||
</:col>
|
||||
</.table>
|
||||
"""
|
||||
end
|
||||
|
||||
def mount(_params, _session, socket) do
|
||||
new_assigns = %{
|
||||
media_profiles: get_media_profiles()
|
||||
}
|
||||
|
||||
{:ok, assign(socket, new_assigns)}
|
||||
end
|
||||
|
||||
def handle_event("formless-input", %{"event" => "toggle_enabled"} = params, socket) do
|
||||
# should_enable = params["value"] == "true"
|
||||
IO.inspect(params)
|
||||
|
||||
{:noreply, socket}
|
||||
end
|
||||
|
||||
defp get_media_profiles do
|
||||
ProfilesQuery.new()
|
||||
|> where([mp], is_nil(mp.marked_for_deletion_at))
|
||||
|> order_by(asc: :name)
|
||||
|> Repo.all()
|
||||
end
|
||||
end
|
||||
Loading…
Reference in a new issue