Add liliform page

This commit is contained in:
Harshad Sharma 2024-05-16 05:07:36 +05:30
parent 55d4f1b2c2
commit a4e04e3980
4 changed files with 125 additions and 7 deletions

View file

@ -3,14 +3,26 @@ defmodule FreediveWeb.LiliformLive do
quote location: :keep, bind_quoted: [opts: opts] do quote location: :keep, bind_quoted: [opts: opts] do
use FreediveWeb, :live_view use FreediveWeb, :live_view
@behaviour FreediveWeb.LiliformLive @behaviour FreediveWeb.LiliformLive
@all [
%{
title: "All",
icon: "all",
active: false
}
]
def mount(_params, _session, socket) do def(mount(_params, _session, socket)) do
socket = assign(socket, :opts, unquote(opts)) socket = assign(socket, :opts, Keyword.get(unquote(opts), :opts, []))
socket = assign(socket, :items, items()) socket = assign(socket, :items, items())
socket = assign(socket, :filters, @all ++ filters())
socket = assign(socket, :query, "")
{:ok, socket} {:ok, socket}
end end
end end
end end
@callback items() :: [map] @callback items() :: [map]
@callback filters() :: [map]
@callback search(query :: String.t()) :: [map]
end end

View file

@ -1,12 +1,13 @@
defmodule FreediveWeb.ServiceLive do defmodule FreediveWeb.ServiceLive do
use FreediveWeb.LiliformLive, use FreediveWeb.LiliformLive
opts: [
name: "Services"
]
def render(assigns) do def render(assigns) do
~H""" ~H"""
<%= inspect(@items) %> <.block class="px-2 py-4">
<.page name="Services">
<FreediveWeb.ServiceLive.Item.item_block items={@items} />
</.page>
</.block>
""" """
end end
@ -14,6 +15,7 @@ defmodule FreediveWeb.ServiceLive do
[ [
%{ %{
name: "sshd", name: "sshd",
path: "/services/ssh",
icon: "blocks", icon: "blocks",
description: "Secure Shell Daemon", description: "Secure Shell Daemon",
enabled: true, enabled: true,
@ -21,6 +23,7 @@ defmodule FreediveWeb.ServiceLive do
}, },
%{ %{
name: "pf", name: "pf",
path: "/services/pf",
icon: "shield", icon: "shield",
description: "Packet Filter", description: "Packet Filter",
enabled: true, enabled: true,
@ -28,6 +31,7 @@ defmodule FreediveWeb.ServiceLive do
}, },
%{ %{
name: "ntpdate", name: "ntpdate",
path: "/services/ntp",
icon: "clock", icon: "clock",
description: "Network Time Protocol Daemon", description: "Network Time Protocol Daemon",
enabled: true, enabled: true,
@ -35,6 +39,7 @@ defmodule FreediveWeb.ServiceLive do
}, },
%{ %{
name: "httpd", name: "httpd",
path: "/services/httpd",
icon: "globe", icon: "globe",
description: "Hypertext Transfer Protocol Daemon", description: "Hypertext Transfer Protocol Daemon",
enabled: false, enabled: false,
@ -42,4 +47,51 @@ defmodule FreediveWeb.ServiceLive do
} }
] ]
end end
def filters() do
[
%{
title: "Running",
key: "running",
icon: "circle-play",
active: true
},
%{
title: "Enabled",
key: "enabled",
icon: "circle-check",
active: false
}
]
end
def search(query) do
items()
|> Enum.filter(fn item ->
String.contains?(String.downcase(item.name), String.downcase(query))
end)
end
end
defmodule FreediveWeb.ServiceLive.Item do
use Liliform.Component
import Liliform.Icon
@doc """
Returns a list of items.
"""
attr :items, :list, default: [], doc: "items"
def item_block(assigns) do
~H"""
<%= for item <- @items do %>
<.link patch={item.path} class="panel-block pt-1">
<span class="panel-icon">
<.icon for={item.icon} color="auto" aria-hidden="true" />
</span>
<div class="mt-2 ml-2"><%= item.name %></div>
</.link>
<% end %>
"""
end
end end

View file

@ -15,6 +15,7 @@ defmodule Liliform do
import Liliform.Label import Liliform.Label
import Liliform.Media import Liliform.Media
import Liliform.Navbar import Liliform.Navbar
import Liliform.Page
import Liliform.Panel import Liliform.Panel
import Liliform.Section import Liliform.Section
import Liliform.SimpleForm import Liliform.SimpleForm

53
lib/liliform/page.ex Normal file
View file

@ -0,0 +1,53 @@
defmodule Liliform.Page do
use Liliform.Component
import Liliform.Icon
import Liliform.Panel
import Liliform.Control
@doc """
Renders a panel as page.
"""
attr :name, :string, required: true, doc: "page name"
attr :class, :string, default: "", doc: "additional classes"
attr :filters, :list, default: [], doc: "filters"
attr :query, :string, default: "", doc: "search query"
attr :rest, :global
slot :inner_block, required: true
def page(assigns) do
assigns =
assigns
|> set_bulma_classes()
~H"""
<.panel class={@class} {@rest} is-info>
<.panel_heading>
<%= @name %>
</.panel_heading>
<.panel_tabs is-hidden-mobile>
<%= for filter <- @filters do %>
<a class={if filter.active, do: "is-active"}><%= filter.title %></a>
<% end %>
</.panel_tabs>
<.panel_tabs is-hidden-tablet>
<%= for filter <- @filters do %>
<a title={filter.title} class={if filter.active, do: "is-active"}>
<.icon for={filter.icon} color="auto" />
</a>
<% end %>
</.panel_tabs>
<.panel_block>
<.control has-icons-left>
<input class="input is-info" type="text" placeholder="Search" name="search" value={@query} />
<.icon for="search" size="1.5rem" aria-hidden="true" is-left />
</.control>
</.panel_block>
<%= render_slot(@inner_block) %>
</.panel>
"""
end
end