From 714417189b706b00a285901129cedbc41c4e36e7 Mon Sep 17 00:00:00 2001 From: Paulo Valim Date: Tue, 30 Jan 2024 10:41:48 +0100 Subject: [PATCH] Add LiveView table component (#2460) --- .../components/core_components.ex | 83 ++++++++++++++++ .../live/hub/secret_list_component.ex | 96 ++++++++----------- mix.lock | 2 + 3 files changed, 123 insertions(+), 58 deletions(-) diff --git a/lib/livebook_web/components/core_components.ex b/lib/livebook_web/components/core_components.ex index 9e132c12f..1f9e60ac0 100644 --- a/lib/livebook_web/components/core_components.ex +++ b/lib/livebook_web/components/core_components.ex @@ -739,4 +739,87 @@ defmodule LivebookWeb.CoreComponents do def hook_prop(value) do Jason.encode!(value) end + + @doc ~S""" + Renders a table with generic styling. + + ## Examples + + <.table id="users" rows={@users}> + <:col :let={user} label="id"><%= user.id %> + <:col :let={user} label="username"><%= user.username %> + + """ + attr :id, :string, required: true + attr :rows, :list, required: true + attr :row_id, :any, default: nil, doc: "the function for generating the row id" + attr :row_click, :any, default: nil, doc: "the function for handling phx-click on each row" + + attr :row_item, :any, + default: &Function.identity/1, + doc: "the function for mapping each row before calling the :col and :action slots" + + slot :col, required: true do + attr :label, :string + end + + slot :action, doc: "the slot for showing user actions in the last table column" + + def table(assigns) do + assigns = + with %{rows: %Phoenix.LiveView.LiveStream{}} <- assigns do + assign(assigns, row_id: assigns.row_id || fn {id, _item} -> id end) + end + + ~H""" +
+ + + + + + + + + + + + + +
+ <%= col[:label] %> + + Actions +
+
+ + + <%= render_slot(col, @row_item.(row)) %> + +
+
+
+ + + <%= render_slot(action, @row_item.(row)) %> + +
+
+
+ """ + end end diff --git a/lib/livebook_web/live/hub/secret_list_component.ex b/lib/livebook_web/live/hub/secret_list_component.ex index b604a7561..caf67512a 100644 --- a/lib/livebook_web/live/hub/secret_list_component.ex +++ b/lib/livebook_web/live/hub/secret_list_component.ex @@ -19,66 +19,46 @@ defmodule LivebookWeb.Hub.SecretListComponent do No secrets here... yet!
- - - - - - - - - - - - - -
+ <:col :let={secret} label="Name"><%= secret.name %> + <:action :let={secret}> + + <.link + id={"hub-secret-#{secret.name}-edit"} + patch={"/#{@edit_path}/#{secret.name}"} + type="button" + role="menuitem" + class="icon-button" > - Name - + + + + <:action :let={secret}> + +
- <%= secret.name %> - - - <.link - id={"hub-secret-#{secret.name}-edit"} - patch={"/#{@edit_path}/#{secret.name}"} - type="button" - role="menuitem" - class="icon-button" - > - <.remix_icon icon="edit-fill" class="text-lg" /> - - - - - -
+ <.remix_icon icon="delete-bin-6-line" class="text-lg" /> + + + +
diff --git a/mix.lock b/mix.lock index d7f291087..1a92bcfdb 100644 --- a/mix.lock +++ b/mix.lock @@ -13,9 +13,11 @@ "ecto": {:hex, :ecto, "3.10.3", "eb2ae2eecd210b4eb8bece1217b297ad4ff824b4384c0e3fdd28aaf96edd6135", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "44bec74e2364d491d70f7e42cd0d690922659d329f6465e89feb8a34e8cd3433"}, "eini": {:hex, :eini_beam, "2.2.3", "4c809b483b0435789c5924642b81ed1cd6fa7d23f5e2efb3e420522a051fa483", [:rebar3], [], "hexpm", "10381b4cb76b8340b492653dae8f6ab7cb372305906ea196d6a1c070516e7a5f"}, "ex_doc": {:hex, :ex_doc, "0.30.9", "d691453495c47434c0f2052b08dd91cc32bc4e1a218f86884563448ee2502dd2", [:mix], [{:earmark_parser, "~> 1.4.31", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "d7aaaf21e95dc5cddabf89063327e96867d00013963eadf2c6ad135506a8bc10"}, + "expo": {:hex, :expo, "0.5.1", "249e826a897cac48f591deba863b26c16682b43711dd15ee86b92f25eafd96d9", [:mix], [], "hexpm", "68a4233b0658a3d12ee00d27d37d856b1ba48607e7ce20fd376958d0ba6ce92b"}, "file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"}, "finch": {:hex, :finch, "0.16.0", "40733f02c89f94a112518071c0a91fe86069560f5dbdb39f9150042f44dcfb1a", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.3", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2.6 or ~> 1.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "f660174c4d519e5fec629016054d60edd822cdfe2b7270836739ac2f97735ec5"}, "floki": {:hex, :floki, "0.34.3", "5e2dcaec5d7c228ce5b1d3501502e308b2d79eb655e4191751a1fe491c37feac", [:mix], [], "hexpm", "9577440eea5b97924b4bf3c7ea55f7b8b6dce589f9b28b096cc294a8dc342341"}, + "gettext": {:hex, :gettext, "0.24.0", "6f4d90ac5f3111673cbefc4ebee96fe5f37a114861ab8c7b7d5b30a1108ce6d8", [:mix], [{:expo, "~> 0.5.1", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "bdf75cdfcbe9e4622dd18e034b227d77dd17f0f133853a1c73b97b3d6c770e8b"}, "hpax": {:hex, :hpax, "0.1.2", "09a75600d9d8bbd064cdd741f21fc06fc1f4cf3d0fcc335e5aa19be1a7235c84", [:mix], [], "hexpm", "2c87843d5a23f5f16748ebe77969880e29809580efdaccd615cd3bed628a8c13"}, "iso8601": {:hex, :iso8601, "1.3.3", "994aff5dfe760f14a8c4f2d8c3cf500371bf1a8cf309c3c0cb510401064223e0", [:rebar3], [], "hexpm", "bcc7767d691e4d8a26e713f48da51abd951bec4e071ae841f371766f96b46834"}, "jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"},