Merge pull request #738 from Lokraan/validated-blocks-address-page-overview
Add mined blocks count to miner (validator) address page overview.pull/826/head
commit
32ce2f9289
@ -0,0 +1,43 @@ |
|||||||
|
defmodule BlockScoutWeb.AddressValidationController do |
||||||
|
@moduledoc """ |
||||||
|
Display all the blocks that this address validates. |
||||||
|
""" |
||||||
|
use BlockScoutWeb, :controller |
||||||
|
|
||||||
|
import BlockScoutWeb.AddressController, only: [transaction_count: 1, validation_count: 1] |
||||||
|
import BlockScoutWeb.Chain, only: [paging_options: 1, next_page_params: 3, split_list_by_page: 1] |
||||||
|
|
||||||
|
alias Explorer.{Chain, Market} |
||||||
|
alias Explorer.ExchangeRates.Token |
||||||
|
|
||||||
|
def index(conn, %{"address_id" => address_hash_string} = params) do |
||||||
|
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), |
||||||
|
{:ok, address} <- Chain.hash_to_address(address_hash) do |
||||||
|
full_options = |
||||||
|
Keyword.merge( |
||||||
|
[necessity_by_association: %{miner: :required, transactions: :optional}], |
||||||
|
paging_options(params) |
||||||
|
) |
||||||
|
|
||||||
|
blocks_plus_one = Chain.get_blocks_validated_by_address(full_options, address) |
||||||
|
{blocks, next_page} = split_list_by_page(blocks_plus_one) |
||||||
|
|
||||||
|
render( |
||||||
|
conn, |
||||||
|
"index.html", |
||||||
|
address: address, |
||||||
|
blocks: blocks, |
||||||
|
transaction_count: transaction_count(address), |
||||||
|
validation_count: validation_count(address), |
||||||
|
exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(), |
||||||
|
next_page_params: next_page_params(next_page, blocks, params) |
||||||
|
) |
||||||
|
else |
||||||
|
:error -> |
||||||
|
unprocessable_entity(conn) |
||||||
|
|
||||||
|
{:error, :not_found} -> |
||||||
|
not_found(conn) |
||||||
|
end |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,137 @@ |
|||||||
|
<section class="container"> |
||||||
|
<%= render BlockScoutWeb.AddressView, "overview.html", assigns %> |
||||||
|
|
||||||
|
<section> |
||||||
|
<div class="card"> |
||||||
|
<div class="card-header"> |
||||||
|
<!-- DESKTOP TAB NAV --> |
||||||
|
<ul class="nav nav-tabs card-header-tabs d-none d-md-inline-flex"> |
||||||
|
<li class="nav-item"> |
||||||
|
<%= link( |
||||||
|
gettext("Transactions"), |
||||||
|
class: "nav-link", |
||||||
|
to: address_transaction_path(@conn, :index, @address.hash) |
||||||
|
) %> |
||||||
|
</li> |
||||||
|
<li class="nav-item"> |
||||||
|
<%= link( |
||||||
|
gettext("Tokens"), |
||||||
|
class: "nav-link", |
||||||
|
to: address_token_path(@conn, :index, @address.hash) |
||||||
|
) %> |
||||||
|
</li> |
||||||
|
<li class="nav-item"> <%= link( |
||||||
|
gettext("Internal Transactions"), |
||||||
|
class: "nav-link", |
||||||
|
"data-test": "internal_transactions_tab_link", |
||||||
|
to: address_internal_transaction_path(@conn, :index, @address.hash) |
||||||
|
) %> |
||||||
|
</li> |
||||||
|
<li class="nav-item"> |
||||||
|
<%= link( |
||||||
|
gettext("Blocks Validated"), |
||||||
|
class: "nav-link active", |
||||||
|
"data-test": "validations_tab_link", |
||||||
|
to: address_validation_path(@conn, :index, @address.hash) |
||||||
|
) %> |
||||||
|
</li> |
||||||
|
<%= if contract?(@address) do %> |
||||||
|
<li class="nav-item"> |
||||||
|
<%= link( |
||||||
|
to: address_contract_path(@conn, :index, @address.hash), |
||||||
|
class: "nav-link") do %> |
||||||
|
<%= gettext("Code") %> |
||||||
|
<%= if smart_contract_verified?(@address) do %> |
||||||
|
<i class="far fa-check-circle"></i> |
||||||
|
<% end %> |
||||||
|
<% end %> |
||||||
|
</li> |
||||||
|
<% end %> |
||||||
|
<%= if smart_contract_with_read_only_functions?(@address) do %> |
||||||
|
<li class="nav-item"> |
||||||
|
<%= link( |
||||||
|
gettext("Read Contract"), |
||||||
|
to: address_read_contract_path(@conn, :index, @address.hash), |
||||||
|
class: "nav-link")%> |
||||||
|
</li> |
||||||
|
<% end %> |
||||||
|
</ul> |
||||||
|
<!-- MOBILE DROPDOWN NAV --> |
||||||
|
<ul class="nav nav-tabs card-header-tabs d-md-none"> |
||||||
|
<li class="nav-item dropdown flex-fill text-center"> |
||||||
|
<a class="nav-link active dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false"><%= gettext "Tokens" %></a> |
||||||
|
<div class="dropdown-menu"> |
||||||
|
<%= link( |
||||||
|
gettext("Transactions"), |
||||||
|
class: "dropdown-item", |
||||||
|
to: address_transaction_path(@conn, :index, @address.hash) |
||||||
|
) %> |
||||||
|
<%= link( |
||||||
|
gettext("Tokens"), |
||||||
|
class: "dropdown-item", |
||||||
|
to: address_token_path(@conn, :index, @address.hash) |
||||||
|
) %> |
||||||
|
<%= link( |
||||||
|
gettext("Internal Transactions"), |
||||||
|
class: "dropdown-item", |
||||||
|
"data-test": "internal_transactions_tab_link", |
||||||
|
to: address_internal_transaction_path(@conn, :index, @address.hash) |
||||||
|
) %> |
||||||
|
<%= link( |
||||||
|
gettext("Blocks Validated"), |
||||||
|
class: "dropdown-item active", |
||||||
|
"data-test": "validations_tab_link", |
||||||
|
to: address_validation_path(@conn, :index, @address.hash) |
||||||
|
) %> |
||||||
|
<%= if contract?(@address) do %> |
||||||
|
<%= link( |
||||||
|
to: address_contract_path(@conn, :index, @address.hash), |
||||||
|
class: "dropdown-item") do %> |
||||||
|
<%= gettext("Code") %> |
||||||
|
<%= if smart_contract_verified?(@address) do %> |
||||||
|
<i class="far fa-check-circle"></i> |
||||||
|
<% end %> |
||||||
|
<% end %> |
||||||
|
<% end %> |
||||||
|
</div> |
||||||
|
</li> |
||||||
|
</ul> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="card-body"> |
||||||
|
<div data-selector="channel-batching-message"> |
||||||
|
<div data-selector="reload-button" class="alert alert-info" class="d-none"> |
||||||
|
<a href="#" class="alert-link"><span data-selector="channel-batching-count"></span> <%= gettext "More validations have come in." %></a> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div data-selector="channel-disconnected-message" class="d-none"> |
||||||
|
<div data-selector="reload-button" class="alert alert-danger"> |
||||||
|
<a href="#" class="alert-link"><%= gettext "Connection Lost, click to load newer validations" %></a> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<h2 class="card-title"><%=gettext("Blocks Validated")%></h2> |
||||||
|
<span data-selector="validations-list"> |
||||||
|
<%= for block <- @blocks do %> |
||||||
|
<%= render BlockScoutWeb.BlockView, "_tile.html", block: block %> |
||||||
|
<% end %> |
||||||
|
</span> |
||||||
|
<div> |
||||||
|
<%= if @next_page_params do %> |
||||||
|
<%= link( |
||||||
|
gettext("Older"), |
||||||
|
class: "button button-secondary button-sm float-right mt-3", |
||||||
|
to: address_validation_path( |
||||||
|
@conn, |
||||||
|
:index, |
||||||
|
@address, |
||||||
|
@next_page_params |
||||||
|
) |
||||||
|
) %> |
||||||
|
<% end %> |
||||||
|
</div> |
||||||
|
</div> <!-- Card Body --> |
||||||
|
</div> <!-- Card --> |
||||||
|
<section> |
||||||
|
</section> |
@ -0,0 +1,94 @@ |
|||||||
|
<section class="container"> |
||||||
|
<%= render( |
||||||
|
OverviewView, |
||||||
|
"_details.html", |
||||||
|
token: @token, |
||||||
|
total_token_transfers: @total_token_transfers, |
||||||
|
total_token_holders: @total_token_holders, |
||||||
|
conn: @conn |
||||||
|
) %> |
||||||
|
|
||||||
|
<section> |
||||||
|
<div class="card"> |
||||||
|
<div class="card-header"> |
||||||
|
<!-- DESKTOP TAB NAV --> |
||||||
|
<ul class="nav nav-tabs card-header-tabs d-none d-md-inline-flex"> |
||||||
|
<li class="nav-item"> |
||||||
|
<%= link( |
||||||
|
gettext("Token Transfers"), |
||||||
|
class: "nav-link active", |
||||||
|
to: token_path(@conn, :show, @token.contract_address_hash) |
||||||
|
) %> |
||||||
|
</li> |
||||||
|
|
||||||
|
<%= if smart_contract_with_read_only_functions?(@token) do %> |
||||||
|
<li class="nav-item"> |
||||||
|
<%= link( |
||||||
|
gettext("Read Contract"), |
||||||
|
to: token_read_contract_path(@conn, :index, @conn.params["id"]), |
||||||
|
class: "nav-link")%> |
||||||
|
</li> |
||||||
|
<% end %> |
||||||
|
|
||||||
|
<li class="nav-item"i> |
||||||
|
<%= link( |
||||||
|
gettext("Token Holders"), |
||||||
|
class: "nav-link", |
||||||
|
"data-test": "token_holders_tab", |
||||||
|
to: token_holder_path(@conn, :index, @token.contract_address_hash) |
||||||
|
) %> |
||||||
|
</li> |
||||||
|
</ul> |
||||||
|
|
||||||
|
<!-- MOBILE DROPDOWN NAV --> |
||||||
|
<ul class="nav nav-tabs card-header-tabs d-md-none"> |
||||||
|
<li class="nav-item dropdown flex-fill text-center"> |
||||||
|
<a class="nav-link active dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false"><%= gettext("Token Transfers") %></a> |
||||||
|
<div class="dropdown-menu"> |
||||||
|
<%= link( |
||||||
|
gettext("Token Transfers"), |
||||||
|
class: "dropdown-item active", |
||||||
|
to: token_path(@conn, :show, @token.contract_address_hash) |
||||||
|
) %> |
||||||
|
<%= if smart_contract_with_read_only_functions?(@token) do %> |
||||||
|
<%= link( |
||||||
|
gettext("Read Contract"), |
||||||
|
to: "#", |
||||||
|
class: "dropdown-item")%> |
||||||
|
<% end %> |
||||||
|
<%= link( |
||||||
|
gettext("Token Holders"), |
||||||
|
class: "dropdown-item", |
||||||
|
to: token_holder_path(@conn, :index, @token.contract_address_hash) |
||||||
|
) %> |
||||||
|
</div> |
||||||
|
</li> |
||||||
|
</ul> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="card-body"> |
||||||
|
<h2 class="card-title"><%= gettext "Token Transfers" %></h2> |
||||||
|
|
||||||
|
<%= if Enum.any?(@transfers) do %> |
||||||
|
<%= for transfer <- @transfers do %> |
||||||
|
<%= render("_token_transfer.html", token: @token, transfer: transfer) %> |
||||||
|
<% end %> |
||||||
|
<% else %> |
||||||
|
<div class="tile tile-muted text-center"> |
||||||
|
<span data-selector="empty-transactions-list"> |
||||||
|
<%= gettext "There are no transfers for this Token." %> |
||||||
|
</span> |
||||||
|
</div> |
||||||
|
<% end %> |
||||||
|
|
||||||
|
<%= if @next_page_params do %> |
||||||
|
<%= link( |
||||||
|
gettext("Older"), |
||||||
|
class: "button button-secondary button-small float-right mt-4", |
||||||
|
to: token_path(@conn, :show, @token.contract_address_hash, @next_page_params) |
||||||
|
) %> |
||||||
|
<% end %> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</section> |
||||||
|
</section> |
@ -0,0 +1,6 @@ |
|||||||
|
defmodule BlockScoutWeb.AddressValidationView do |
||||||
|
use BlockScoutWeb, :view |
||||||
|
|
||||||
|
import BlockScoutWeb.AddressView, |
||||||
|
only: [contract?: 1, smart_contract_verified?: 1, smart_contract_with_read_only_functions?: 1] |
||||||
|
end |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue