forked from hiway/freedive
Add liliform page
This commit is contained in:
parent
55d4f1b2c2
commit
a4e04e3980
4 changed files with 125 additions and 7 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
53
lib/liliform/page.ex
Normal 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
|
Loading…
Reference in a new issue