Skip to content

Commit

Permalink
feat: Phoenix.Stream for Table component (#739)
Browse files Browse the repository at this point in the history
  • Loading branch information
phgrey authored Oct 5, 2023
1 parent d03e9d9 commit e49ea8b
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 4 deletions.
2 changes: 2 additions & 0 deletions config/dev.exs
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,5 @@ config :phoenix, :stacktrace_depth, 20

# Initialize plugs at runtime for faster development compilation
config :phoenix, :plug_init_mode, :runtime

# config :phoenix_live_view, debug_heex_annotations: true
20 changes: 17 additions & 3 deletions lib/moon/design/table.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ defmodule Moon.Design.Table do
@doc "Sorting of the table, format [field:, \"ASC\"|\"DESC\"]. If given, component will sort given items before displaying"
prop(sort, :keyword, default: [])

@doc "The list of items to be rendered. If item does not have id - than index is used instead"
@doc "The list of items to be rendered. If item does not have id - than index is used instead. Able to work with streams"
prop(items, :generator, required: true)

@doc "Event that firset on row click"
Expand Down Expand Up @@ -64,6 +64,9 @@ defmodule Moon.Design.Table do
@doc "Additional classes for a table tag"
prop(class, :css_class)

@doc "Additional attributes for tbody tag"
prop(body_attrs, :map, default: %{})

def render(assigns) do
~F"""
<table
Expand Down Expand Up @@ -112,8 +115,8 @@ defmodule Moon.Design.Table do
{/for}
</tr>
</thead>
<tbody>
{#for {item, row_index} <- Enum.with_index(@items |> add_index_as |> sort_items(@sort))}
<tbody {...@body_attrs}>
{#for {row_index, item} <- stream_data(assigns)}
<tr
class={merge([
(is_selected(item.id, @selected) && @selected_bg) || @row_bg,
Expand Down Expand Up @@ -182,4 +185,15 @@ defmodule Moon.Design.Table do
"2xl" -> "text-moon-14 py-5 px-3"
end
end

defp stream_data(%{items: stream = %Phoenix.LiveView.LiveStream{}}) do
stream
end

defp stream_data(%{items: items, sort: sort}) when is_list(items) do
items
|> add_index_as()
|> sort_items(sort)
|> Enum.with_index(&{&2, &1})
end
end
85 changes: 85 additions & 0 deletions lib/moon_web/examples/design/table_example/stream.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
defmodule MoonWeb.Examples.Design.TableExample.Stream do
@moduledoc false

use Moon.LiveView
use MoonWeb, :example

alias Moon.Design.Table
alias Moon.Design.Table.Column
alias Moon.Components.Renderers.Datetime

def mount(_params, _session, socket) do
{:ok, stream(socket, :models, models())}
end

defp models() do
Enum.map(1..5, fn x ->
%{
id: x,
name: "Name #{x}",
created_at: DateTime.add(DateTime.utc_now(), -3600 + x)
}
end)
end

def render(assigns) do
~F"""
<div>
<Table items={model <- @streams.models} selected={nil} body_attrs={%{"phx-update" => "stream"}}>
<Column name="id" label="ID">
{model.id}
</Column>
<Column name="name" label="First Name">
{model.name}
</Column>
<Column name="created_at" label="Created at">
<Datetime value={model.created_at} />
</Column>
</Table>
</div>
"""
end

def code() do
"""
use Phoenix.LiveView
alias Moon.Design.Table
alias Moon.Design.Table.Column
alias Moon.Components.Renderers.Datetime
def mount(_params, _session, socket) do
{:ok, stream(socket, :models, models())}
end
defp models() do
Enum.map(1..5, fn x ->
%{
id: x,
name: "Name \#{x}",
created_at: DateTime.add(DateTime.utc_now(), -3600 + x)
}
end)
end
def render(assigns) do
~F\"""
<div>
<Table items={model <- @streams.models} selected={nil} body_attrs={%{"phx-update" => "stream"}}>
<Column name="id" label="ID">
{model.id}
</Column>
<Column name="name" label="First Name">
{model.name}
</Column>
<Column name="created_at" label="Created at">
<Datetime value={model.created_at} />
</Column>
</Table>
</div>
\"""
end
"""
end
end
10 changes: 10 additions & 0 deletions lib/moon_web/pages/design/table_page.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@ defmodule MoonWeb.Pages.Design.TablePage do

alias Moon.Design.Table
alias MoonWeb.Components.Page
alias MoonWeb.Components.ExampleAndCode
alias MoonWeb.Components.ComponentPageDescription
alias MoonWeb.Components.PropsTable
alias MoonWeb.Components.ExamplesList
alias MoonWeb.Examples.Design.TableExample

# import Phoenix.Component, only: [live_render: 3]

data(breadcrumbs, :any,
default: [
%{
Expand Down Expand Up @@ -50,6 +53,13 @@ defmodule MoonWeb.Pages.Design.TablePage do
TableExample.Responsive
]} />
<ExampleAndCode id="example-table-example-stream" title="Phoenix stream">
<:example>
<TableExample.Stream id="table-example-stream" container={{:div, class: "w-full"}} />
</:example>
<:code>{TableExample.Stream.code()}</:code>
</ExampleAndCode>
<PropsTable title="Table props" module={Table} />
<PropsTable title="Table.Column props" module={Table.Column} />
<PropsTable module={Table.Input} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ defmodule MoonWeb.Examples.Breadcrumb.FiveAndMoreItemsTest do
# TODO: fix test

test "should open and close Breadcrumb panel", %{conn: conn} do
{:ok, view, _html} = live(conn, "/example/BreadcrumbExample.FiveAndMoreItems")
{:ok, _view, _html} = live(conn, "/example/BreadcrumbExample.FiveAndMoreItems")

# assert view
# |> element("#breadcrumb_5 ol.hidden[id=breadcrumb_5_inner_breadcrumb_flyout]")
Expand Down
1 change: 1 addition & 0 deletions test/moon_web/pages/examples_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ defmodule MoonWeb.Pages.ExamplesTest do
with {:ok, list} <- :application.get_key(:moon, :modules) do
list
|> Enum.filter(&(&1 |> Module.split() |> Enum.take(2) == ~w|MoonWeb Examples|))
|> Enum.filter(&(&1 != MoonWeb.Examples.Design.TableExample.Stream))
|> Enum.each(fn example ->
path =
MoonWeb.Router.Helpers.live_path(
Expand Down

0 comments on commit e49ea8b

Please sign in to comment.