Move overview outside transaction details tabs

Co-authored-by: tmecklem <timothy@mecklem.com>
Co-authored-by: katibest <best.kati@gmail.com>
pull/99/head
Tim Mecklem 7 years ago committed by jimmay5469
parent c089e6831a
commit 25de5f1156
  1. 17
      apps/explorer_web/lib/explorer_web/controllers/internal_transaction_controller.ex
  2. 12
      apps/explorer_web/lib/explorer_web/controllers/transaction_controller.ex
  3. 24
      apps/explorer_web/lib/explorer_web/controllers/transaction_log_controller.ex
  4. 1
      apps/explorer_web/lib/explorer_web/router.ex
  5. 43
      apps/explorer_web/lib/explorer_web/templates/internal_transaction/index.html.eex
  6. 96
      apps/explorer_web/lib/explorer_web/templates/transaction/overview.html.eex
  7. 131
      apps/explorer_web/lib/explorer_web/templates/transaction/show.html.eex
  8. 61
      apps/explorer_web/lib/explorer_web/templates/transaction_log/index.html.eex
  9. 22
      apps/explorer_web/test/explorer_web/controllers/internal_transaction_controller_test.exs
  10. 16
      apps/explorer_web/test/explorer_web/controllers/transaction_controller_test.exs
  11. 4
      apps/explorer_web/test/explorer_web/controllers/transaction_log_controller_test.exs
  12. 2
      apps/explorer_web/test/explorer_web/features/contributor_browsing_test.exs

@ -1,17 +0,0 @@
defmodule ExplorerWeb.InternalTransactionController do
use ExplorerWeb, :controller
alias Explorer.Transaction.Service, as: Transaction
def index(conn, %{"transaction_id" => transaction_id}) do
hash = String.downcase(transaction_id)
internal_transactions = Transaction.internal_transactions(hash)
render(
conn,
internal_transactions: internal_transactions,
transaction_hash: hash
)
end
end

@ -3,9 +3,11 @@ defmodule ExplorerWeb.TransactionController do
import Ecto.Query
alias Explorer.Log
alias Explorer.Repo.NewRelic, as: Repo
alias Explorer.Transaction
alias Explorer.TransactionForm
alias Explorer.Transaction.Service
alias Explorer.Transaction.Service.Query
def index(conn, %{"last_seen" => last_seen}) do
@ -64,13 +66,19 @@ defmodule ExplorerWeb.TransactionController do
def show(conn, params) do
transaction =
Transaction
|> Query.by_hash(params["id"])
|> Query.by_hash(String.downcase(params["id"]))
|> Query.include_addresses()
|> Query.include_receipt()
|> Query.include_block()
|> Repo.one()
|> TransactionForm.build_and_merge()
render(conn, "show.html", transaction: transaction)
internal_transactions = Service.internal_transactions(transaction.hash)
render(
conn,
internal_transactions: internal_transactions,
transaction: transaction
)
end
end

@ -5,18 +5,36 @@ defmodule ExplorerWeb.TransactionLogController do
alias Explorer.Log
alias Explorer.Repo.NewRelic, as: Repo
alias Explorer.Transaction
alias Explorer.TransactionForm
alias Explorer.Transaction.Service
alias Explorer.Transaction.Service.Query
def index(conn, %{"transaction_id" => transaction_id}) do
hash = String.downcase(transaction_id)
transaction_hash = String.downcase(transaction_id)
transaction =
Transaction
|> Query.by_hash(transaction_hash)
|> Query.include_addresses()
|> Query.include_receipt()
|> Query.include_block()
|> Repo.one()
|> TransactionForm.build_and_merge()
logs =
from(
log in Log,
join: transaction in assoc(log, :transaction),
preload: [:address],
where: fragment("lower(?)", transaction.hash) == ^hash
where: fragment("lower(?)", transaction.hash) == ^transaction_hash
)
render(conn, "index.html", logs: Repo.paginate(logs), transaction_hash: hash)
render(
conn,
"index.html",
logs: Repo.paginate(logs),
transaction: transaction
)
end
end

@ -74,7 +74,6 @@ defmodule ExplorerWeb.Router do
resources "/transactions", TransactionController, only: [:index, :show] do
resources("/logs", TransactionLogController, only: [:index], as: :log)
resources("/internal", InternalTransactionController, only: [:index])
end
resources "/addresses", AddressController, only: [:show] do

@ -1,43 +0,0 @@
<section class="container__section transaction">
<div class="transaction__header">
<h1 class="transaction__heading"><%= gettext "Internal Transactions" %></h1>
<h3 class="transaction__subheading"><%= @transaction_hash %></h3>
</div>
<div class="transaction__container">
<div class="transaction__tabs">
<h2 class="transaction__tab"><%= link(gettext("Overview"), to: transaction_path(@conn, :show, @conn.assigns.locale, @transaction_hash), class: "transaction__link") %></h2>
<h2 class="transaction__tab transaction__tab--active"><%= link(gettext("Internal Transactions"), to: transaction_internal_transaction_path(@conn, :index, @conn.assigns.locale, @transaction_hash), class: "transaction__link transaction__link--active") %></h2>
<h2 class="transaction__tab"><%= link(gettext("Logs"), to: transaction_log_path(@conn, :index, @conn.assigns.locale, @transaction_hash), class: "transaction__link") %></h2>
</div>
<div class="internal-transaction__container">
<table class="internal-transaction__table">
<thead>
<th class="internal-transaction__column-header"><%= gettext "Type" %></th>
<th class="internal-transaction__column-header"><%= gettext "From" %></th>
<th class="internal-transaction__column-header"><%= gettext "To" %></th>
<th class="internal-transaction__column-header"><%= gettext "Value" %></th>
<th class="internal-transaction__column-header"><%= gettext "Gas Limit" %></th>
</thead>
<%= for transaction <- @internal_transactions do %>
<tgroup>
<tr>
<td><%= transaction.call_type %></td>
<td class="internal-transaction__to-address">
<%= link(transaction.to_address.hash,
to: address_path(@conn, :show, @conn.assigns.locale, transaction.to_address.hash),
class: "transaction-log__link") %>
</td>
<td class="internal-transaction__from-address">
<%= link(transaction.from_address.hash,
to: address_path(@conn, :show, @conn.assigns.locale, transaction.from_address.hash),
class: "transaction-log__link") %>
</td>
<td><%= transaction.value %></td>
<td><%= ExplorerWeb.TransactionView.format_gas_limit(transaction.gas) %></td>
</tr>
</tgroup>
<% end %>
</table>
</div>
</div>
</section>

@ -0,0 +1,96 @@
<div class="transaction__header">
<h1 class="transaction__heading"><%= gettext "Transaction Details" %></h1>
<h3 class="transaction__subheading"><%= @transaction.hash %></h3>
</div>
<div class="transaction__container">
<div class="transaction__attributes">
<div class="transaction__column">
<dl>
<div class="transaction__item">
<dt class="transaction__item-key"><%= gettext "Transaction Hash" %></dt>
<dd class="transaction__item-value" title="<%= @transaction.hash %>"><%= @transaction.hash %></dd>
</div>
<div class="transaction__item">
<dt class="transaction__item-key"><%= gettext "Transaction Status" %></dt>
<dd class="transaction__item-value transaction__item-value--status">
<div class="transaction__status">
<%= @transaction.formatted_status %>
<div class="transaction__dot transaction__dot--<%= @transaction.status %>"></div>
</div>
</dd>
</div>
<div class="transaction__item">
<dt class="transaction__item-key"><%= gettext "Block Number" %></dt>
<dd class="transaction__item-value">
<span class="transaction__item--primary">
<%= link(@transaction.block_number, to: block_path(@conn, :show, @conn.assigns.locale, @transaction.block_number), class: "transaction__link") %>
</span>
<span class="transaction__item--secondary">
(<%= gettext "%{confirmations} block confirmations", confirmations: @transaction.confirmations %>)
</span>
</dd>
</div>
<div class="transaction__item">
<dt class="transaction__item-key"><%= gettext "Age" %></dt>
<dd class="transaction__item-value" title="<%= @transaction.formatted_timestamp %>"><%= @transaction.formatted_age %></dd>
</div>
<div class="transaction__item">
<dt class="transaction__item-key"><%= gettext "Value" %></dt>
<dd class="transaction__item-value"><%= Decimal.div(Decimal.new(@transaction.value), Decimal.new(1_000_000_000_000_000_000)) |> Decimal.to_string(:normal) %> <%= gettext "POA" %></dd>
</div>
<div class="transaction__item">
<dt class="transaction__item-key"><%= gettext "From" %></dt>
<dd class="transaction__item-value">
<%= if @transaction.from_address do %>
<%= link(@transaction.from_address.hash, to: address_path(@conn, :show, @conn.assigns.locale, @transaction.from_address.hash), class: "transaction__link") %>
<% else %>
<%= gettext "Pending" %>
<% end %>
</dd>
</div>
<div class="transaction__item">
<dt class="transaction__item-key"><%= gettext "To" %></dt>
<dd class="transaction__item-value">
<%= if @transaction.to_address do %>
<%= link(@transaction.to_address.hash, to: address_path(@conn, :show, @conn.assigns.locale, @transaction.to_address.hash), class: "transaction__link") %>
<% else %>
<%= gettext "Pending" %>
<% end %>
</dd>
</div>
</dl>
</div>
<div class="transaction__column">
<dl>
<div class="transaction__item">
<dt class="transaction__item-key"><%= gettext "First Seen" %></dt>
<dd class="transaction__item-value" title="<%= @transaction.first_seen %>"><%= @transaction.first_seen %></dd>
</div>
<div class="transaction__item">
<dt class="transaction__item-key"><%= gettext "Last Seen" %></dt>
<dd class="transaction__item-value" title="<%= @transaction.last_seen %>"><%= @transaction.last_seen %></dd>
</div>
<div class="transaction__item">
<dt class="transaction__item-key"><%= gettext "Gas Limit" %></dt>
<dd class="transaction__item-value"><%= format_gas_limit(@transaction.gas) %></dd>
</div>
<div class="transaction__item">
<dt class="transaction__item-key"><%= gettext "Gas Price" %></dt>
<dd class="transaction__item-value"><%= @transaction.gas_price |> Cldr.Number.to_string! %> (<%= Decimal.div(Decimal.new(@transaction.gas_price), Decimal.new(1_000_000_000)) |> Decimal.to_string(:normal) %> Gwei)</dd>
</div>
<div class="transaction__item">
<dt class="transaction__item-key"><%= gettext "Cumulative Gas Used" %></dt>
<dd class="transaction__item-value"><%= @transaction.cumulative_gas_used %></dd>
</div>
<div class="transaction__item">
<dt class="transaction__item-key"><%= gettext "Nonce" %></dt>
<dd class="transaction__item-value"><%= @transaction.nonce %></dd>
</div>
<div class="transaction__item">
<dt class="transaction__item-key"><%= gettext "Input" %></dt>
<dd class="transaction__item-value" title="<%= @transaction.input %>"><%= @transaction.input %></dd>
</div>
</dl>
</div>
</div>
</div>

@ -1,103 +1,44 @@
<section class="container__section transaction">
<div class="transaction__header">
<h1 class="transaction__heading"><%= gettext "Transaction Details" %></h1>
<h3 class="transaction__subheading"><%= @transaction.hash %></h3>
</div>
<%= render "overview.html", assigns %>
<div class="transaction__container">
<div class="transaction__tabs">
<h2 class="transaction__tab transaction__tab--active"><%= link(gettext("Overview"), to: transaction_path(@conn, :show, @conn.assigns.locale, @transaction.hash), class: "transaction__link transaction__link--active") %></h2>
<h2 class="transaction__tab"><%= link(gettext("Internal Transactions"), to: transaction_internal_transaction_path(@conn, :index, @conn.assigns.locale, @transaction.hash), class: "transaction__link") %></h2>
<h2 class="transaction__tab transaction__tab--active"><%= link(gettext("Internal Transactions"), to: transaction_path(@conn, :show, @conn.assigns.locale, @transaction.hash), class: "transaction__link transaction__link--active") %></h2>
<h2 class="transaction__tab"><%= link(gettext("Logs"), to: transaction_log_path(@conn, :index, @conn.assigns.locale, @transaction.hash), class: "transaction__link") %></h2>
</div>
<div class="transaction__attributes">
<div class="transaction__column">
<dl>
<div class="transaction__item">
<dt class="transaction__item-key"><%= gettext "Transaction Hash" %></dt>
<dd class="transaction__item-value" title="<%= @transaction.hash %>"><%= @transaction.hash %></dd>
</div>
<div class="transaction__item">
<dt class="transaction__item-key"><%= gettext "Transaction Status" %></dt>
<dd class="transaction__item-value transaction__item-value--status">
<div class="transaction__status">
<%= @transaction.formatted_status %>
<div class="transaction__dot transaction__dot--<%= @transaction.status %>"></div>
</div>
</dd>
</div>
<div class="transaction__item">
<dt class="transaction__item-key"><%= gettext "Block Number" %></dt>
<dd class="transaction__item-value">
<span class="transaction__item--primary">
<%= link(@transaction.block_number, to: block_path(@conn, :show, @conn.assigns.locale, @transaction.block_number), class: "transaction__link") %>
</span>
<span class="transaction__item--secondary">
(<%= gettext "%{confirmations} block confirmations", confirmations: @transaction.confirmations %>)
</span>
</dd>
</div>
<div class="transaction__item">
<dt class="transaction__item-key"><%= gettext "Age" %></dt>
<dd class="transaction__item-value" title="<%= @transaction.formatted_timestamp %>"><%= @transaction.formatted_age %></dd>
</div>
<div class="transaction__item">
<dt class="transaction__item-key"><%= gettext "Value" %></dt>
<dd class="transaction__item-value"><%= Decimal.div(Decimal.new(@transaction.value), Decimal.new(1_000_000_000_000_000_000)) |> Decimal.to_string(:normal) %> <%= gettext "POA" %></dd>
</div>
<div class="transaction__item">
<dt class="transaction__item-key"><%= gettext "From" %></dt>
<dd class="transaction__item-value">
<%= if @transaction.from_address do %>
<%= link(@transaction.from_address.hash, to: address_path(@conn, :show, @conn.assigns.locale, @transaction.from_address.hash), class: "transaction__link") %>
<% else %>
<%= gettext "Pending" %>
<% end %>
</dd>
</div>
<div class="transaction__item">
<dt class="transaction__item-key"><%= gettext "To" %></dt>
<dd class="transaction__item-value">
<%= if @transaction.to_address do %>
<%= link(@transaction.to_address.hash, to: address_path(@conn, :show, @conn.assigns.locale, @transaction.to_address.hash), class: "transaction__link") %>
<% else %>
<%= gettext "Pending" %>
<% end %>
</dd>
</div>
</dl>
</div>
<div class="transaction__column">
<dl>
<div class="transaction__item">
<dt class="transaction__item-key"><%= gettext "First Seen" %></dt>
<dd class="transaction__item-value" title="<%= @transaction.first_seen %>"><%= @transaction.first_seen %></dd>
</div>
<div class="transaction__item">
<dt class="transaction__item-key"><%= gettext "Last Seen" %></dt>
<dd class="transaction__item-value" title="<%= @transaction.last_seen %>"><%= @transaction.last_seen %></dd>
</div>
<div class="transaction__item">
<dt class="transaction__item-key"><%= gettext "Gas Limit" %></dt>
<dd class="transaction__item-value"><%= format_gas_limit(@transaction.gas) %></dd>
</div>
<div class="transaction__item">
<dt class="transaction__item-key"><%= gettext "Gas Price" %></dt>
<dd class="transaction__item-value"><%= @transaction.gas_price |> Cldr.Number.to_string! %> (<%= Decimal.div(Decimal.new(@transaction.gas_price), Decimal.new(1_000_000_000)) |> Decimal.to_string(:normal) %> Gwei)</dd>
</div>
<div class="transaction__item">
<dt class="transaction__item-key"><%= gettext "Cumulative Gas Used" %></dt>
<dd class="transaction__item-value"><%= @transaction.cumulative_gas_used %></dd>
</div>
<div class="transaction__item">
<dt class="transaction__item-key"><%= gettext "Nonce" %></dt>
<dd class="transaction__item-value"><%= @transaction.nonce %></dd>
</div>
<div class="transaction__item">
<dt class="transaction__item-key"><%= gettext "Input" %></dt>
<dd class="transaction__item-value" title="<%= @transaction.input %>"><%= @transaction.input %></dd>
</div>
</dl>
</div>
<div class="internal-transaction__container">
<%= if length(@internal_transactions) > 0 do %>
<table class="internal-transaction__table">
<thead>
<th class="internal-transaction__column-header"><%= gettext "Type" %></th>
<th class="internal-transaction__column-header"><%= gettext "From" %></th>
<th class="internal-transaction__column-header"><%= gettext "To" %></th>
<th class="internal-transaction__column-header"><%= gettext "Value" %></th>
<th class="internal-transaction__column-header"><%= gettext "Gas Limit" %></th>
</thead>
<%= for transaction <- @internal_transactions do %>
<tgroup>
<tr>
<td><%= transaction.call_type %></td>
<td class="internal-transaction__to-address">
<%= link(transaction.to_address.hash,
to: address_path(@conn, :show, @conn.assigns.locale, transaction.to_address.hash),
class: "transaction-log__link") %>
</td>
<td class="internal-transaction__from-address">
<%= link(transaction.from_address.hash,
to: address_path(@conn, :show, @conn.assigns.locale, transaction.from_address.hash),
class: "transaction-log__link") %>
</td>
<td><%= transaction.value %></td>
<td><%= ExplorerWeb.TransactionView.format_gas_limit(transaction.gas) %></td>
</tr>
</tgroup>
<% end %>
</table>
<% else %>
<p>There are no Internal Transactions</p>
<% end %>
</div>
</div>
</section>

@ -1,39 +1,40 @@
<section class="container__section">
<div class="transaction-log__header">
<h1 class="transaction-log__heading"><%= gettext "Transaction Logs" %></h1>
<h3 class="transaction-log__subheading"><%= @transaction_hash %></h3>
</div>
<%= render ExplorerWeb.TransactionView, "overview.html", assigns %>
<div class="transaction-log">
<div class="transaction-log__tabs">
<h2 class="transaction-log__tab"><%= link(gettext("Overview"), to: transaction_path(@conn, :show, @conn.assigns.locale, @transaction_hash), class: "transaction-log__link") %></h2>
<h2 class="transaction__tab"><%= link(gettext("Internal Transactions"), to: transaction_internal_transaction_path(@conn, :index, @conn.assigns.locale, @transaction_hash), class: "transaction__link") %></h2>
<h2 class="transaction-log__tab transaction-log__tab--active"><%= link(gettext("Logs"), to: transaction_log_path(@conn, :index, @conn.assigns.locale, @transaction_hash), class: "transaction-log__link transaction-log__link--active") %></h2>
<h2 class="transaction__tab"><%= link(gettext("Internal Transactions"), to: transaction_path(@conn, :show, @conn.assigns.locale, @transaction.hash), class: "transaction__link") %></h2>
<h2 class="transaction__tab transaction__tab--active"><%= link(gettext("Logs"), to: transaction_log_path(@conn, :index, @conn.assigns.locale, @transaction.hash), class: "transaction__link transaction__link--active") %></h2>
</div>
<div class="transaction-log__container">
<table class="transaction-log__table">
<thead>
<th class="transaction-log__column-header"><%= gettext "Address" %></th>
<th class="transaction-log__column-header"><%= gettext "Topic" %></th>
</thead>
<%= for log <- @logs.entries do %>
<tgroup>
<tr>
<td><%= link(log.address.hash, to: address_path(@conn, :show, @conn.assigns.locale, log.address.hash), class: "transaction-log__link") %></td>
<td><%= log.first_topic %></td>
</tr>
<% unless is_nil(log.second_topic) do %>
<tr><td>topic[1]</td><td><%= log.second_topic %></td></tr>
<% end %>
<% unless is_nil(log.third_topic) do %>
<tr><td>topic[2]</td><td><%= log.third_topic %></td></tr>
<% end %>
<% unless is_nil(log.data) do %>
<tr><td>↠</td><td><%= log.data %></td></tr>
<% end %>
</tgroup>
<% end %>
</table>
<%= if length(@logs.entries) > 0 do %>
<table class="transaction-log__table">
<thead>
<th class="transaction-log__column-header"><%= gettext "Address" %></th>
<th class="transaction-log__column-header"><%= gettext "Topic" %></th>
</thead>
<%= for log <- @logs.entries do %>
<tgroup>
<tr>
<td><%= link(log.address.hash, to: address_path(@conn, :show, @conn.assigns.locale, log.address.hash), class: "transaction-log__link") %></td>
<td><%= log.first_topic %></td>
</tr>
<% unless is_nil(log.second_topic) do %>
<tr><td>topic[1]</td><td><%= log.second_topic %></td></tr>
<% end %>
<% unless is_nil(log.third_topic) do %>
<tr><td>topic[2]</td><td><%= log.third_topic %></td></tr>
<% end %>
<% unless is_nil(log.data) do %>
<tr><td>↠</td><td><%= log.data %></td></tr>
<% end %>
</tgroup>
<% end %>
</table>
<% else %>
<p>There are no logs currently.</p>
<% end %>
</div>
</div>
</section>

@ -1,22 +0,0 @@
defmodule ExplorerWeb.InternalTransactionControllerTest do
use ExplorerWeb.ConnCase
import ExplorerWeb.Router.Helpers, only: [transaction_internal_transaction_path: 4]
describe "GET index/2" do
test "returns internal transactions for the transaction", %{conn: conn} do
transaction = insert(:transaction)
internal_transaction = insert(:internal_transaction, transaction_id: transaction.id)
path =
transaction_internal_transaction_path(ExplorerWeb.Endpoint, :index, :en, transaction.hash)
conn = get(conn, path)
first_internal_transaction = List.first(conn.assigns.internal_transactions)
assert conn.assigns.transaction_hash == transaction.hash
assert first_internal_transaction.id == internal_transaction.id
end
end
end

@ -1,6 +1,8 @@
defmodule ExplorerWeb.TransactionControllerTest do
use ExplorerWeb.ConnCase
import ExplorerWeb.Router.Helpers, only: [transaction_path: 4]
describe "GET index/2" do
test "returns a transaction with a receipt", %{conn: conn} do
transaction = insert(:transaction)
@ -71,5 +73,19 @@ defmodule ExplorerWeb.TransactionControllerTest do
assert conn.assigns.transaction.id == transaction.id
assert conn.assigns.transaction.block_number == ""
end
test "returns internal transactions for the transaction", %{conn: conn} do
transaction = insert(:transaction)
internal_transaction = insert(:internal_transaction, transaction_id: transaction.id)
path = transaction_path(ExplorerWeb.Endpoint, :show, :en, transaction.hash)
conn = get(conn, path)
first_internal_transaction = List.first(conn.assigns.internal_transactions)
assert conn.assigns.transaction.hash == transaction.hash
assert first_internal_transaction.id == internal_transaction.id
end
end
end

@ -10,7 +10,9 @@ defmodule ExplorerWeb.TransactionLogControllerTest do
address = insert(:address)
insert(:log, receipt: receipt, address: address)
path = transaction_log_path(ExplorerWeb.Endpoint, :index, :en, transaction.hash)
conn = get(conn, path)
first_log = List.first(conn.assigns.logs.entries)
assert first_log.receipt_id == receipt.id
end
@ -18,7 +20,9 @@ defmodule ExplorerWeb.TransactionLogControllerTest do
test "assigns no logs when there are none", %{conn: conn} do
transaction = insert(:transaction)
path = transaction_log_path(ExplorerWeb.Endpoint, :index, :en, transaction.hash)
conn = get(conn, path)
assert Enum.count(conn.assigns.logs.entries) == 0
end
end

@ -190,7 +190,7 @@ defmodule ExplorerWeb.UserListTest do
|> visit("/en/transactions/0xSk8")
|> click(link("Logs"))
|> assert_has(css(".transaction-log__link", text: "0xlincoln"))
|> click(link("0xlincoln"))
|> click(css(".transaction-log__link", text: "0xlincoln"))
|> assert_has(css(".address__subheading", text: "0xlincoln"))
|> click(css(".address__link", text: "Transactions To"))
|> assert_has(css(".transactions__link--long-hash", text: "0xSk8"))

Loading…
Cancel
Save