From efd5f1d126cd609be9a4381550f9a95d2e8a2c37 Mon Sep 17 00:00:00 2001 From: Nikos Papadakis Date: Fri, 24 Nov 2023 00:56:38 +0200 Subject: [PATCH] app: alpine.js + dropdown --- .editorconfig | 4 + app/assets/js/app.js | 17 ++- app/assets/package-lock.json | 33 +++++ app/assets/package.json | 5 + app/lib/prymn_web/components/button.ex | 2 +- .../prymn_web/components/core_components.ex | 56 +++++++++ .../components/layouts/app.html.heex | 23 ++-- app/lib/prymn_web/live/server_live/show.ex | 116 ++++++++++-------- 8 files changed, 192 insertions(+), 64 deletions(-) create mode 100644 app/assets/package-lock.json create mode 100644 app/assets/package.json diff --git a/.editorconfig b/.editorconfig index 01be004..122b31f 100644 --- a/.editorconfig +++ b/.editorconfig @@ -2,6 +2,10 @@ root = true charset = utf-8 end_of_line = lf +[*.js] +indent_style = space +indent_size = 2 + [*.nix] indent_style = space indent_size = 2 diff --git a/app/assets/js/app.js b/app/assets/js/app.js index df0cdd9..b7a5ad9 100644 --- a/app/assets/js/app.js +++ b/app/assets/js/app.js @@ -15,15 +15,26 @@ // import "some-package" // -// Include phoenix_html to handle method=PUT/DELETE in forms and buttons. import "phoenix_html" -// Establish Phoenix Socket and LiveView configuration. import {Socket} from "phoenix" import {LiveSocket} from "phoenix_live_view" import topbar from "../vendor/topbar" +import Alpine from "alpinejs" + +Alpine.start() +window.Alpine = Alpine let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content") -let liveSocket = new LiveSocket("/live", Socket, {params: {_csrf_token: csrfToken}}) +let liveSocket = new LiveSocket("/live", Socket, { + params: {_csrf_token: csrfToken}, + dom: { + onBeforeElUpdated(from, to) { + if (from._x_dataStack) { + window.Alpine.clone(from, to) + } + } + } +}) // Show progress bar on live navigation and form submits topbar.config({barColors: {0: "#29d"}, shadowColor: "rgba(0, 0, 0, .3)"}) diff --git a/app/assets/package-lock.json b/app/assets/package-lock.json new file mode 100644 index 0000000..ff530ff --- /dev/null +++ b/app/assets/package-lock.json @@ -0,0 +1,33 @@ +{ + "name": "assets", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "alpinejs": "^3.13.3" + } + }, + "node_modules/@vue/reactivity": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.1.5.tgz", + "integrity": "sha512-1tdfLmNjWG6t/CsPldh+foumYFo3cpyCHgBYQ34ylaMsJ+SNHQ1kApMIa8jN+i593zQuaw3AdWH0nJTARzCFhg==", + "dependencies": { + "@vue/shared": "3.1.5" + } + }, + "node_modules/@vue/shared": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.1.5.tgz", + "integrity": "sha512-oJ4F3TnvpXaQwZJNF3ZK+kLPHKarDmJjJ6jyzVNDKH9md1dptjC7lWR//jrGuLdek/U6iltWxqAnYOu8gCiOvA==" + }, + "node_modules/alpinejs": { + "version": "3.13.3", + "resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.13.3.tgz", + "integrity": "sha512-WZ6WQjkAOl+WdW/jukzNHq9zHFDNKmkk/x6WF7WdyNDD6woinrfXCVsZXm0galjbco+pEpYmJLtwlZwcOfIVdg==", + "dependencies": { + "@vue/reactivity": "~3.1.1" + } + } + } +} diff --git a/app/assets/package.json b/app/assets/package.json new file mode 100644 index 0000000..63b363b --- /dev/null +++ b/app/assets/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "alpinejs": "^3.13.3" + } +} diff --git a/app/lib/prymn_web/components/button.ex b/app/lib/prymn_web/components/button.ex index a9e9c18..34ec4d8 100644 --- a/app/lib/prymn_web/components/button.ex +++ b/app/lib/prymn_web/components/button.ex @@ -36,7 +36,7 @@ defmodule PrymnWeb.Button do assigns, :style, [ - "inline-flex justify-center items-end rounded-2xl shadow transition-colors active:shadow-sm", + "inline-flex justify-center items-center rounded-2xl shadow transition-colors active:shadow-sm", by_variant(assigns.variant), by_size(assigns.size), assigns[:class] diff --git a/app/lib/prymn_web/components/core_components.ex b/app/lib/prymn_web/components/core_components.ex index adf7fc3..8dde58c 100644 --- a/app/lib/prymn_web/components/core_components.ex +++ b/app/lib/prymn_web/components/core_components.ex @@ -587,6 +587,62 @@ defmodule PrymnWeb.CoreComponents do """ end + @doc """ + A simple dropdown menu + """ + + attr :title, :string, default: nil + attr :position, :string, default: "left", values: ~w(left right) + + slot :button + slot :item + + def dropdown(assigns) do + ~H""" +
+ + +
+ """ + end + ## JS Commands def show(js \\ %JS{}, selector) do diff --git a/app/lib/prymn_web/components/layouts/app.html.heex b/app/lib/prymn_web/components/layouts/app.html.heex index ab86cad..f63ac91 100644 --- a/app/lib/prymn_web/components/layouts/app.html.heex +++ b/app/lib/prymn_web/components/layouts/app.html.heex @@ -16,18 +16,17 @@

- <.link class="border-r border-l px-3 py-4 hover:bg-white" href={~p"/users/settings"}> - <.icon name="hero-user" /> - <.icon name="hero-chevron-down" /> - - <.link - title="Log out" - class="border-r px-3 py-4 hover:bg-white" - method="DELETE" - href={~p"/auth/log_out"} - > - <.icon name="hero-x-mark" /> - + <.dropdown> + <:button> + <.icon name="hero-user-solid" /> + + <:item> + <.link href={~p"/users/settings"}>Settings + + <:item> + <.link method="DELETE" href={~p"/auth/log_out"}>Log out + +
diff --git a/app/lib/prymn_web/live/server_live/show.ex b/app/lib/prymn_web/live/server_live/show.ex index 378eaf1..a8ac1f7 100644 --- a/app/lib/prymn_web/live/server_live/show.ex +++ b/app/lib/prymn_web/live/server_live/show.ex @@ -1,5 +1,4 @@ defmodule PrymnWeb.ServerLive.Show do - alias DBConnection.App use PrymnWeb, :live_view require Logger @@ -7,44 +6,38 @@ defmodule PrymnWeb.ServerLive.Show do @impl true def mount(_params, _session, socket) do - {:ok, socket} + # TODO: A more lightweight call instead of listing all data? + servers = Servers.list_servers() + {:ok, assign(socket, :servers, servers)} end @impl true def render(assigns) do ~H"""
- <.header> - - - - +
+ <.dropdown title="Select a different server"> + <:button>Server <%= @server.name %> + <:item :for={server <- Enum.filter(@servers, fn s -> s.id != @server.id end)}> + <.link + patch={~p"/servers/#{server}"} + class="block text-sm text-gray-700" + role="menuitem" + > + <%= server.name %> + + + + + <.indicator message={@health.message} /> +
- <:subtitle> - <%= @server.public_ip %> - - <:actions> +
New App - - Quick actions <.icon name="hero-chevron-down" class="ml-1" /> - - - -
- <%= for {name, task} <- @health.tasks do %> - Background task in progress: <%= name %> -

<%= task.progress %> complete

- <% end %> + <.dropdown> + <:button> + Quick actions + + <:item> + Test + + +
+
+ <%= @server.public_ip %> +
+

Background task in progress: <%= name %>

+

<%= task.progress %> complete

@@ -229,4 +223,30 @@ defmodule PrymnWeb.ServerLive.Show do |> JS.hide() |> JS.show(to: "#server-name", display: "flex") end + + defp indicator(assigns) do + ~H""" + + <%= case @message do %> + <% "Connected" -> %> + + + <% "Disconnected" -> %> + + <% _ -> %> + + <% end %> + + """ + end end