Show Block details.

pull/2/head
CJ Bryan and Matt Olenick 7 years ago
parent 68c701da33
commit 22b86b59de
  1. 1
      assets/css/components/_all.scss
  2. 51
      assets/css/components/_block-detail.scss
  3. 5
      lib/explorer/forms/block_form.ex
  4. 15
      lib/explorer_web/controllers/block_controller.ex
  5. 1
      lib/explorer_web/router.ex
  6. 69
      lib/explorer_web/templates/block/show.html.eex
  7. 2
      lib/explorer_web/templates/page/index.html.eex
  8. 4
      lib/explorer_web/views/block_view.ex
  9. 66
      priv/gettext/default.pot
  10. 66
      priv/gettext/en/LC_MESSAGES/default.po
  11. 6
      test/explorer/forms/block_form_test.exs
  12. 11
      test/explorer_web/controllers/block_controller_test.exs
  13. 14
      test/explorer_web/features/contributor_browsing_test.exs

@ -1,5 +1,6 @@
@import "blocks"; @import "blocks";
@import "container"; @import "container";
@import "header"; @import "header";
@import "block-detail";
@import "transactions"; @import "transactions";
@import "footer"; @import "footer";

@ -0,0 +1,51 @@
.block-detail {
&__container {
@extend %paper;
padding: explorer-size(-1) explorer-size(0);
}
&__title {
@include explorer-typography("title");
color: explorer-color("slate", "100");
margin: 0;
}
&__column {
@include explorer-typography("body1");
}
&__item {
display: flex;
flex-direction: row;
justify-content: space-between;
dt {
color: explorer-color("slate", "100");
min-width: explorer-size(3);
}
dd {
color: explorer-color("slate", "100");
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
}
}
@media (min-width: $explorer-breakpoint-lg) {
.block-detail {
&__attributes {
display: flex;
align-items: top;
justify-content: top;
}
&__column {
width: explorer-size(1);
flex: 1;
margin-right: explorer-size(1);
& + & { margin-left: explorer-size(1); }
}
}
}

@ -9,6 +9,7 @@ defmodule Explorer.BlockForm do
block |> Map.merge(%{ block |> Map.merge(%{
transactions_count: block |> get_transactions_count, transactions_count: block |> get_transactions_count,
age: block |> calculate_age, age: block |> calculate_age,
formatted_timestamp: block |> format_timestamp,
}) })
end end
@ -22,4 +23,8 @@ defmodule Explorer.BlockForm do
def calculate_age(block) do def calculate_age(block) do
block.timestamp |> Timex.from_now block.timestamp |> Timex.from_now
end end
def format_timestamp(block) do
block.timestamp |> Timex.format!("%b-%d-%Y %H:%M:%S %p %Z", :strftime)
end
end end

@ -0,0 +1,15 @@
defmodule ExplorerWeb.BlockController do
use ExplorerWeb, :controller
import Ecto.Query
alias Explorer.Block
alias Explorer.Repo
alias Explorer.BlockForm
def show(conn, params) do
block = Block
|> where(id: ^params["id"])
|> first |> Repo.one
|> BlockForm.build
render(conn, "show.html", block: block)
end
end

@ -29,5 +29,6 @@ defmodule ExplorerWeb.Router do
scope "/:locale", ExplorerWeb do scope "/:locale", ExplorerWeb do
pipe_through :browser # Use the default browser stack pipe_through :browser # Use the default browser stack
get "/", PageController, :index get "/", PageController, :index
resources "/blocks", BlockController, only: [:show]
end end
end end

@ -0,0 +1,69 @@
<section class="container__section">
<div class="block-detail__container">
<h2 class="block-detail__title">
<%= gettext "Block #%{number} Details", number: @block.number %>
</h2>
<div class="block-detail__attributes">
<div class="block-detail__column">
<dl>
<div class="block-detail__item">
<dt><%= gettext "Number" %></dt>
<dd><%= @block.number %></dd>
</div>
<div class="block-detail__item">
<dt><%= gettext "Age" %></dt>
<dd><%= @block.age %></dd>
</div>
<div class="block-detail__item">
<dt><%= gettext "Timestamp" %></dt>
<dd><%= @block.formatted_timestamp %></dd>
</div>
<div class="block-detail__item">
<dt><%= gettext "Transactions" %></dt>
<dd><%= @block.transactions_count %></dd>
</div>
<div class="block-detail__item">
<dt><%= gettext "Hash" %></dt>
<dd><%= @block.hash %></dd>
</div>
<div class="block-detail__item">
<dt><%= gettext "Parent Hash" %></dt>
<dd><%= @block.parent_hash %></dd>
</div>
<div class="block-detail__item">
<dt><%= gettext "Miner" %></dt>
<dd><%= @block.miner %></dd>
</div>
<div class="block-detail__item">
<dt><%= gettext "Difficulty" %></dt>
<dd><%= @block.difficulty %></dd>
</div>
</dl>
</div>
<div class="block-detail__column">
<dl>
<div class="block-detail__item">
<dt><%= gettext "Total Difficulty" %></dt>
<dd><%= @block.total_difficulty %></dd>
</div>
<div class="block-detail__item">
<dt><%= gettext "Size" %></dt>
<dd><%= @block.size %></dd>
</div>
<div class="block-detail__item">
<dt><%= gettext "Gas Used" %></dt>
<dd><%= @block.gas_used %></dd>
</div>
<div class="block-detail__item">
<dt><%= gettext "Gas Limit" %></dt>
<dd><%= @block.gas_limit %></dd>
</div>
<div class="block-detail__item">
<dt><%= gettext "Nonce" %></dt>
<dd><%= @block.nonce %></dd>
</div>
</dl>
</div>
</div>
</div>
</section>

@ -16,7 +16,7 @@
<tbody> <tbody>
<%= for block <- @blocks do %> <%= for block <- @blocks do %>
<tr class="blocks__row"> <tr class="blocks__row">
<td class="blocks__column blocks__column--height"><%= block.number %></td> <td class="blocks__column blocks__column--height"><%= link(block.number, to: block_path(@conn, :show, @conn.assigns.locale, block.id)) %></td>
<td class="blocks__column blocks__column--age"><%= block.age %></td> <td class="blocks__column blocks__column--age"><%= block.age %></td>
<td class="blocks__column blocks__column--transactions-count"><%= block.transactions_count %></td> <td class="blocks__column blocks__column--transactions-count"><%= block.transactions_count %></td>
<td class="blocks__column blocks__column--gas-used"><%= block.gas_used %></td> <td class="blocks__column blocks__column--gas-used"><%= block.gas_used %></td>

@ -0,0 +1,4 @@
defmodule ExplorerWeb.BlockView do
use ExplorerWeb, :view
@dialyzer :no_match
end

@ -1,52 +1,86 @@
#, elixir-format #: lib/explorer_web/templates/block/show.html.eex:14
#: lib/explorer_web/templates/page/index.html.eex:11 #: lib/explorer_web/templates/page/index.html.eex:11
#: lib/explorer_web/templates/page/index.html.eex:40 #: lib/explorer_web/templates/page/index.html.eex:39
msgid "Age" msgid "Age"
msgstr "" msgstr ""
#, elixir-format #: lib/explorer_web/templates/page/index.html.eex:38
#: lib/explorer_web/templates/page/index.html.eex:39
msgid "Block" msgid "Block"
msgstr "" msgstr ""
#, elixir-format
#: lib/explorer_web/templates/page/index.html.eex:4 #: lib/explorer_web/templates/page/index.html.eex:4
msgid "Blocks" msgid "Blocks"
msgstr "" msgstr ""
#, elixir-format
#: lib/explorer_web/templates/layout/_footer.html.eex:2 #: lib/explorer_web/templates/layout/_footer.html.eex:2
msgid "Copyright %{year} POA" msgid "Copyright %{year} POA"
msgstr "" msgstr ""
#, elixir-format #: lib/explorer_web/templates/block/show.html.eex:54
#: lib/explorer_web/templates/page/index.html.eex:13 #: lib/explorer_web/templates/page/index.html.eex:13
msgid "Gas Used" msgid "Gas Used"
msgstr "" msgstr ""
#, elixir-format #: lib/explorer_web/templates/block/show.html.eex:26
#: lib/explorer_web/templates/page/index.html.eex:38 #: lib/explorer_web/templates/page/index.html.eex:37
msgid "Hash" msgid "Hash"
msgstr "" msgstr ""
#, elixir-format
#: lib/explorer_web/templates/page/index.html.eex:10 #: lib/explorer_web/templates/page/index.html.eex:10
msgid "Height" msgid "Height"
msgstr "" msgstr ""
#, elixir-format #: lib/explorer_web/templates/layout/_header.html.eex:6
#: lib/explorer_web/templates/layout/_header.html.eex:4
#: lib/explorer_web/templates/layout/app.html.eex:7 #: lib/explorer_web/templates/layout/app.html.eex:7
msgid "POA Network Explorer" msgid "POA Network Explorer"
msgstr "" msgstr ""
#, elixir-format #: lib/explorer_web/templates/block/show.html.eex:22
#: lib/explorer_web/templates/page/index.html.eex:12 #: lib/explorer_web/templates/page/index.html.eex:12
#: lib/explorer_web/templates/page/index.html.eex:32 #: lib/explorer_web/templates/page/index.html.eex:31
msgid "Transactions" msgid "Transactions"
msgstr "" msgstr ""
#, elixir-format #: lib/explorer_web/templates/page/index.html.eex:40
#: lib/explorer_web/templates/page/index.html.eex:41
msgid "Value" msgid "Value"
msgstr "" msgstr ""
#: lib/explorer_web/templates/block/show.html.eex:4
msgid "Block #%{number} Details"
msgstr ""
#: lib/explorer_web/templates/block/show.html.eex:38
msgid "Difficulty"
msgstr ""
#: lib/explorer_web/templates/block/show.html.eex:58
msgid "Gas Limit"
msgstr ""
#: lib/explorer_web/templates/block/show.html.eex:34
msgid "Miner"
msgstr ""
#: lib/explorer_web/templates/block/show.html.eex:62
msgid "Nonce"
msgstr ""
#: lib/explorer_web/templates/block/show.html.eex:10
msgid "Number"
msgstr ""
#: lib/explorer_web/templates/block/show.html.eex:30
msgid "Parent Hash"
msgstr ""
#: lib/explorer_web/templates/block/show.html.eex:50
msgid "Size"
msgstr ""
#: lib/explorer_web/templates/block/show.html.eex:18
msgid "Timestamp"
msgstr ""
#: lib/explorer_web/templates/block/show.html.eex:46
msgid "Total Difficulty"
msgstr ""

@ -10,55 +10,89 @@ msgid ""
msgstr "" msgstr ""
"Language: en\n" "Language: en\n"
#, elixir-format #: lib/explorer_web/templates/block/show.html.eex:14
#: lib/explorer_web/templates/page/index.html.eex:11 #: lib/explorer_web/templates/page/index.html.eex:11
#: lib/explorer_web/templates/page/index.html.eex:40 #: lib/explorer_web/templates/page/index.html.eex:39
msgid "Age" msgid "Age"
msgstr "Age" msgstr "Age"
#, elixir-format #: lib/explorer_web/templates/page/index.html.eex:38
#: lib/explorer_web/templates/page/index.html.eex:39
msgid "Block" msgid "Block"
msgstr "Block" msgstr "Block"
#, elixir-format
#: lib/explorer_web/templates/page/index.html.eex:4 #: lib/explorer_web/templates/page/index.html.eex:4
msgid "Blocks" msgid "Blocks"
msgstr "Blocks" msgstr "Blocks"
#, elixir-format
#: lib/explorer_web/templates/layout/_footer.html.eex:2 #: lib/explorer_web/templates/layout/_footer.html.eex:2
msgid "Copyright %{year} POA" msgid "Copyright %{year} POA"
msgstr "%{year} POA Network Ltd. All rights reserved" msgstr "%{year} POA Network Ltd. All rights reserved"
#, elixir-format #: lib/explorer_web/templates/block/show.html.eex:54
#: lib/explorer_web/templates/page/index.html.eex:13 #: lib/explorer_web/templates/page/index.html.eex:13
msgid "Gas Used" msgid "Gas Used"
msgstr "Gas Used" msgstr "Gas Used"
#, elixir-format #: lib/explorer_web/templates/block/show.html.eex:26
#: lib/explorer_web/templates/page/index.html.eex:38 #: lib/explorer_web/templates/page/index.html.eex:37
msgid "Hash" msgid "Hash"
msgstr "Hash" msgstr "Hash"
#, elixir-format
#: lib/explorer_web/templates/page/index.html.eex:10 #: lib/explorer_web/templates/page/index.html.eex:10
msgid "Height" msgid "Height"
msgstr "Height" msgstr "Height"
#, elixir-format #: lib/explorer_web/templates/layout/_header.html.eex:6
#: lib/explorer_web/templates/layout/_header.html.eex:4
#: lib/explorer_web/templates/layout/app.html.eex:7 #: lib/explorer_web/templates/layout/app.html.eex:7
msgid "POA Network Explorer" msgid "POA Network Explorer"
msgstr "POA Network Explorer" msgstr "POA Network Explorer"
#, elixir-format #: lib/explorer_web/templates/block/show.html.eex:22
#: lib/explorer_web/templates/page/index.html.eex:12 #: lib/explorer_web/templates/page/index.html.eex:12
#: lib/explorer_web/templates/page/index.html.eex:32 #: lib/explorer_web/templates/page/index.html.eex:31
msgid "Transactions" msgid "Transactions"
msgstr "Transactions" msgstr "Transactions"
#, elixir-format #: lib/explorer_web/templates/page/index.html.eex:40
#: lib/explorer_web/templates/page/index.html.eex:41
msgid "Value" msgid "Value"
msgstr "Value" msgstr "Value"
#: lib/explorer_web/templates/block/show.html.eex:4
msgid "Block #%{number} Details"
msgstr "Block #%{number} Details"
#: lib/explorer_web/templates/block/show.html.eex:38
msgid "Difficulty"
msgstr "Difficulty"
#: lib/explorer_web/templates/block/show.html.eex:58
msgid "Gas Limit"
msgstr "Gas Limit"
#: lib/explorer_web/templates/block/show.html.eex:34
msgid "Miner"
msgstr "Validator"
#: lib/explorer_web/templates/block/show.html.eex:62
msgid "Nonce"
msgstr "Nonce"
#: lib/explorer_web/templates/block/show.html.eex:10
msgid "Number"
msgstr "Height"
#: lib/explorer_web/templates/block/show.html.eex:30
msgid "Parent Hash"
msgstr "Parent Hash"
#: lib/explorer_web/templates/block/show.html.eex:50
msgid "Size"
msgstr "Size"
#: lib/explorer_web/templates/block/show.html.eex:18
msgid "Timestamp"
msgstr "Timestamp"
#: lib/explorer_web/templates/block/show.html.eex:46
msgid "Total Difficulty"
msgstr "Total Difficulty"

@ -24,5 +24,11 @@ defmodule Explorer.BlockFormTest do
block = insert(:block, timestamp: Timex.now |> Timex.shift(hours: -1)) block = insert(:block, timestamp: Timex.now |> Timex.shift(hours: -1))
assert BlockForm.build(block).age == "1 hour ago" assert BlockForm.build(block).age == "1 hour ago"
end end
test "formats a timestamp" do
date = "Jan-23-2018 10:48:56 AM Etc/UTC"
block = insert(:block, timestamp: Timex.parse!(date, "%b-%d-%Y %H:%M:%S %p %Z", :strftime))
assert BlockForm.build(block).formatted_timestamp == date
end
end end
end end

@ -0,0 +1,11 @@
defmodule ExplorerWeb.BlockControllerTest do
use ExplorerWeb.ConnCase
describe "GET show/3" do
test "returns a block", %{conn: conn} do
insert(:block, id: 3)
conn = get(conn, "/en/blocks/3")
assert conn.assigns.block.id == 3
end
end
end

@ -1,7 +1,7 @@
defmodule ExplorerWeb.UserListTest do defmodule ExplorerWeb.UserListTest do
use ExplorerWeb.FeatureCase, async: true use ExplorerWeb.FeatureCase, async: true
import Wallaby.Query, only: [css: 1, css: 2] import Wallaby.Query, only: [css: 1, css: 2, link: 1]
@logo css("img.header__logo") @logo css("img.header__logo")
@ -17,7 +17,7 @@ defmodule ExplorerWeb.UserListTest do
test "views blocks on the home page", %{session: session} do test "views blocks on the home page", %{session: session} do
insert_list(4, :block, %{number: 1, timestamp: Timex.now |> Timex.shift(hours: -1), gas_used: 10}) insert_list(4, :block, %{number: 1, timestamp: Timex.now |> Timex.shift(hours: -1), gas_used: 10})
fifth_block = insert(:block, %{number: 1, timestamp: Timex.now |> Timex.shift(hours: -1), gas_used: 10}) fifth_block = insert(:block, %{number: 311, hash: "0xMrCoolBlock", timestamp: Timex.now |> Timex.shift(hours: -1), miner: "Heathcliff", size: 9999999, nonce: "once upon a nonce", gas_used: 1010101, gas_limit: 5030101})
insert_list(3, :transaction, block: fifth_block) insert_list(3, :transaction, block: fifth_block)
session session
@ -28,6 +28,16 @@ defmodule ExplorerWeb.UserListTest do
|> assert_has(css(".blocks__column--transactions-count", count: 1, text: "3")) |> assert_has(css(".blocks__column--transactions-count", count: 1, text: "3"))
|> assert_has(css(".blocks__column--age", count: 5, text: "1 hour ago")) |> assert_has(css(".blocks__column--age", count: 5, text: "1 hour ago"))
|> assert_has(css(".blocks__column--gas-used", count: 5, text: "10")) |> assert_has(css(".blocks__column--gas-used", count: 5, text: "10"))
session
|> click(link("311"))
|> assert_has(css(".block-detail__item", text: "0xMrCoolBlock"))
|> assert_has(css(".block-detail__item", text: "Heathcliff"))
|> assert_has(css(".block-detail__item", text: "9999999"))
|> assert_has(css(".block-detail__item", text: "1 hour ago"))
|> assert_has(css(".block-detail__item", text: "5030101"))
|> assert_has(css(".block-detail__item", text: "once upon a nonce"))
|> assert_has(css(".block-detail__item", text: "1010101"))
end end
test "views transactions on the home page", %{session: session} do test "views transactions on the home page", %{session: session} do

Loading…
Cancel
Save