Added tooltipsfor Block Details Page + fixed height issue on main Blockscout Page + Added ERC 721 image to the token transfers page(required additional logic)

pull/2625/head
Yegor San 5 years ago
parent 0515bc8647
commit 4c70b0b5ab
  1. 29
      apps/block_scout_web/assets/css/app.scss
  2. 346
      apps/block_scout_web/assets/css/components/_card.scss
  3. 74
      apps/block_scout_web/assets/css/components/_custom_tooltips_block_details.scss
  4. 10
      apps/block_scout_web/assets/css/components/_erc721_token_image_container.scss
  5. 13
      apps/block_scout_web/assets/package-lock.json
  6. 35
      apps/block_scout_web/lib/block_scout_web/templates/block/overview.html.eex
  7. 7
      apps/block_scout_web/lib/block_scout_web/templates/tokens/overview/_details.html.eex
  8. 6
      apps/block_scout_web/lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex

@ -1,10 +1,12 @@
@import "./mixins"; @import "./mixins";
/* Phoenix flash messages */ /* Phoenix flash messages */
.alert:empty { .alert:empty {
display: none; display: none;
} }
/* This file is for your main application css. */ /* This file is for your main application css. */
// Font Awesome // Font Awesome
@ -13,13 +15,10 @@ $fa-font-path: "~@fortawesome/fontawesome-free/webfonts";
@import "fa-brands"; @import "fa-brands";
@import "fa-regular"; @import "fa-regular";
@import "fa-solid"; @import "fa-solid";
// Bootstrap Core CSS // Bootstrap Core CSS
@import "node_modules/bootstrap/scss/functions"; @import "node_modules/bootstrap/scss/functions";
@import "node_modules/bootstrap/scss/mixins"; @import "node_modules/bootstrap/scss/mixins";
@import "theme/variables"; @import "theme/variables";
@import "node_modules/bootstrap/scss/root"; @import "node_modules/bootstrap/scss/root";
@import "node_modules/bootstrap/scss/reboot"; @import "node_modules/bootstrap/scss/reboot";
@import "node_modules/bootstrap/scss/grid"; @import "node_modules/bootstrap/scss/grid";
@ -38,7 +37,6 @@ $fa-font-path: "~@fortawesome/fontawesome-free/webfonts";
@import "node_modules/bootstrap/scss/utilities/position"; @import "node_modules/bootstrap/scss/utilities/position";
@import "node_modules/bootstrap/scss/utilities/borders"; @import "node_modules/bootstrap/scss/utilities/borders";
@import "node_modules/bootstrap/scss/progress"; @import "node_modules/bootstrap/scss/progress";
// Bootstrap Components // Bootstrap Components
@import "node_modules/bootstrap/scss/alert"; @import "node_modules/bootstrap/scss/alert";
@import "node_modules/bootstrap/scss/badge"; @import "node_modules/bootstrap/scss/badge";
@ -50,13 +48,10 @@ $fa-font-path: "~@fortawesome/fontawesome-free/webfonts";
@import "node_modules/bootstrap/scss/pagination"; @import "node_modules/bootstrap/scss/pagination";
@import "node_modules/bootstrap/scss/tables"; @import "node_modules/bootstrap/scss/tables";
@import "node_modules/bootstrap/scss/transitions"; @import "node_modules/bootstrap/scss/transitions";
// Code highlight // Code highlight
@import "node_modules/highlight.js/styles/default"; @import "node_modules/highlight.js/styles/default";
//Custom theme //Custom theme
@import "theme/fonts"; @import "theme/fonts";
// Custom SCSS // Custom SCSS
@import "layout"; @import "layout";
@import "typography"; @import "typography";
@ -113,15 +108,19 @@ $fa-font-path: "~@fortawesome/fontawesome-free/webfonts";
@import "components/new_smart_contract"; @import "components/new_smart_contract";
@import "components/radio_big"; @import "components/radio_big";
@import "components/btn_no_border"; @import "components/btn_no_border";
@import "components/custom_tooltips_block_details";
@import "components/_erc721_token_image_container";
@import "theme/dark-theme"; @import "theme/dark-theme";
:export { :export {
dashboardBannerChartAxisFontColor: $dashboard-banner-chart-axis-font-color; dashboardBannerChartAxisFontColor: $dashboard-banner-chart-axis-font-color;
dashboardLineColorMarket: $dashboard-line-color-market; dashboardLineColorMarket: $dashboard-line-color-market;
dashboardLineColorPrice: $dashboard-line-color-price; dashboardLineColorPrice: $dashboard-line-color-price;
primary: $primary; primary: $primary;
secondary: $secondary; secondary: $secondary;
darkprimary: $dark-primary; darkprimary: $dark-primary;
darksecondary: $dark-secondary; darksecondary: $dark-secondary;
} }

@ -7,244 +7,214 @@ $card-background-1: $primary !default;
$card-background-1-text-color: #fff !default; $card-background-1-text-color: #fff !default;
$card-tab-icon-color: #20b760 !default; $card-tab-icon-color: #20b760 !default;
$card-tab-icon-color-active: #fff !default; $card-tab-icon-color-active: #fff !default;
.card { .card {
background-color: $card-background-color; background-color: $card-background-color;
border-radius: $card-default-border-radius; border-radius: $card-default-border-radius;
border: none; border: none;
box-shadow: 0 0 30px 0 rgba(202, 199, 226, 0.5); box-shadow: 0 0 30px 0 rgba(202, 199, 226, 0.5);
margin-bottom: $common-container-margin; margin-bottom: $common-container-margin;
.block-details-row {
.block-details-row { flex-direction: row;
flex-direction: row;
@include media-breakpoint-down(sm) {
flex-direction: column;
}
.block-detail-el {
& + .block-detail-el {
@include media-breakpoint-down(sm) { @include media-breakpoint-down(sm) {
margin-top: 6px; flex-direction: column;
}
.block-detail-el {
&+.block-detail-el {
@include media-breakpoint-down(sm) {
margin-top: 6px;
}
}
} }
}
} }
}
} }
.card-background-1 { .card-background-1 {
background-color: $card-background-1; background-color: $card-background-1;
color: $card-background-1-text-color;
a:not(.dropdown-item),
a:not(.dropdown-item):hover {
color: $card-background-1-text-color; color: $card-background-1-text-color;
} a:not(.dropdown-item),
a:not(.dropdown-item):hover {
color: $card-background-1-text-color;
}
} }
.card-header { .card-header {
background: transparent; background: transparent;
border-bottom: 1px solid $base-border-color; border-bottom: 1px solid $base-border-color;
padding: $card-vertical-padding $card-horizontal-padding; padding: $card-vertical-padding $card-horizontal-padding;
&-tabs {
&-tabs { margin: (-$card-spacer-y) (-$card-spacer-x);
margin: (-$card-spacer-y) (-$card-spacer-x); }
}
} }
.card-title { .card-title {
font-size: 18px; font-size: 18px;
font-weight: normal; font-weight: normal;
line-height: 1.2rem; line-height: 1.2rem;
margin-bottom: 2rem; margin-bottom: 2rem;
&.lg-card-title {
&.lg-card-title { @media (max-width: 374px) {
@media (max-width: 374px) { font-size: 13px;
font-size: 13px; }
} }
} &.margin-bottom-md {
margin-bottom: 25px;
&.margin-bottom-md { }
margin-bottom: 25px; &.margin-bottom-sm {
} margin-bottom: 15px;
}
&.margin-bottom-sm { &.margin-bottom-xs {
margin-bottom: 15px; margin-bottom: 10px;
} }
&.margin-bottom-0 {
&.margin-bottom-xs { margin-bottom: 0;
margin-bottom: 10px; }
} .card-title-container & {
line-height: 1.2;
&.margin-bottom-0 { margin: 0;
margin-bottom: 0; @include media-breakpoint-down(sm) {
} margin-bottom: 25px;
}
.card-title-container & {
line-height: 1.2;
margin: 0;
@include media-breakpoint-down(sm) {
margin-bottom: 25px;
} }
}
} }
.card-subtitle { .card-subtitle {
color: #333; color: #333;
font-size: 12px; font-size: 12px;
font-weight: normal; font-weight: normal;
line-height: 1.2; line-height: 1.2;
margin: 0 0 30px; margin: 0 0 30px;
&.margin-bottom-0 {
&.margin-bottom-0 { margin-bottom: 0;
margin-bottom: 0; }
}
} }
.card-title-container { .card-title-container {
align-items: center; align-items: center;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
padding: 25px $card-horizontal-padding; padding: 25px $card-horizontal-padding;
@include media-breakpoint-down(sm) {
@include media-breakpoint-down(sm) { flex-direction: column;
flex-direction: column; }
}
} }
.card-title-controls { .card-title-controls {
align-items: center; align-items: center;
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
@include media-breakpoint-down(sm) {
flex-direction: column;
}
.card-title-control {
margin-right: 20px;
&:last-child {
margin-right: 0;
}
@include media-breakpoint-down(sm) { @include media-breakpoint-down(sm) {
margin-bottom: 20px; flex-direction: column;
margin-right: 0; }
.card-title-control {
&:last-child { margin-right: 20px;
margin-bottom: 0; &:last-child {
} margin-right: 0;
}
@include media-breakpoint-down(sm) {
margin-bottom: 20px;
margin-right: 0;
&:last-child {
margin-bottom: 0;
}
}
} }
}
} }
.card-body { .card-body {
padding: $card-horizontal-padding; padding: $card-horizontal-padding;
} }
.card-body-flex-column-space-between { .card-body-flex-column-space-between {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-between; justify-content: space-between;
} }
.card-server-response-body { .card-server-response-body {
max-height: 400px; max-height: 400px;
overflow-y: auto; overflow-y: auto;
} }
.card-chain-blocks { .card-chain-blocks {
height: auto; height: auto;
[class*="col-"]:last-child {
[class*="col-"]:last-child { .tile {
.tile { margin-bottom: 0;
margin-bottom: 0; }
} }
}
} }
.card-chain-transactions { .card-chain-transactions {
height: auto; height: auto;
.tile {
.tile { margin-bottom: 0;
margin-bottom: 0; }
}
} }
.card-tabs { .card-tabs {
align-items: center; align-items: center;
border-top-left-radius: $card-default-border-radius; border-top-left-radius: $card-default-border-radius;
border-top-right-radius: $card-default-border-radius; border-top-right-radius: $card-default-border-radius;
border-bottom: 1px solid $base-border-color; border-bottom: 1px solid $base-border-color;
display: flex; display: flex;
justify-content: flex-start; justify-content: flex-start;
overflow: hidden; overflow: hidden;
@include media-breakpoint-down(md) {
@include media-breakpoint-down(md) { flex-direction: column;
flex-direction: column; }
}
} }
.card-tab { .card-tab {
align-items: center; align-items: center;
background-color: $card-background-color; background-color: $card-background-color;
color: #333; color: #333;
cursor: pointer; cursor: pointer;
display: flex; display: flex;
font-size: 14px; font-size: 14px;
font-weight: normal; font-weight: normal;
height: 70px; height: 70px;
padding: 0 25px; padding: 0 25px;
text-align: center; text-align: center;
transition: $transition-cont; transition: $transition-cont;
&:hover {
&:hover { background-color: rgba($card-tab-active, .15);
background-color: rgba($card-tab-active, .15); color: $card-tab-active;
color: $card-tab-active; text-decoration: none;
text-decoration: none;
}
@include media-breakpoint-down(md) {
display: none;
width: 100%;
}
.fa-check-circle {
color: $card-tab-icon-color;
margin-left: 6px;
}
&.active {
background-color: $card-tab-active;
color: #fff;
cursor: default;
text-decoration: none;
.fa-check-circle {
color: $card-tab-icon-color-active;
} }
@include media-breakpoint-down(md) { @include media-breakpoint-down(md) {
cursor: pointer;
display: flex;
order: -1;
&::after {
border-bottom: 0;
border-left: 0.3em solid transparent;
border-right: 0.3em solid transparent;
border-top: 0.3em solid;
content: "";
display: inline-block;
height: 0;
margin-left: 10px;
width: 0;
}
&.noCaret::after {
display: none; display: none;
} width: 100%;
} }
} .fa-check-circle {
} color: $card-tab-icon-color;
margin-left: 6px;
}
&.active {
background-color: $card-tab-active;
color: #fff;
cursor: default;
text-decoration: none;
.fa-check-circle {
color: $card-tab-icon-color-active;
}
@include media-breakpoint-down(md) {
cursor: pointer;
display: flex;
order: -1;
&::after {
border-bottom: 0;
border-left: 0.3em solid transparent;
border-right: 0.3em solid transparent;
border-top: 0.3em solid;
content: "";
display: inline-block;
height: 0;
margin-left: 10px;
width: 0;
}
&.noCaret::after {
display: none;
}
}
}
}

@ -0,0 +1,74 @@
/* Custom Tooltips for Block Details Page */
.tooltipCustom {
position: relative;
display: inline-block;
}
.tooltipCustom .tooltiptextTopMiner {
visibility: hidden;
position: absolute;
width: 50%;
background-color: white;
color: #5c34a2;
text-align: center;
border-radius: 6px;
left: 25%;
bottom: 100%;
padding: 15px 0px;
display: inline-block;
z-index: 1;
font-family: Nunito;
margin-bottom: 15px;
opacity: 0;
transition: opacity 0.5s;
}
.tooltipCustom .tooltiptextTopMiner::after {
content: '';
position: absolute;
top: 100%;
left: 50%;
margin-left: -5px;
border-width: 5px;
border-style: solid;
border-color: white transparent transparent transparent;
}
.tooltipCustom:hover .tooltiptextTopMiner {
visibility: visible;
opacity: 1;
}
.tooltipCustom .tooltiptextTopR {
visibility: hidden;
position: absolute;
width: 50%;
background-color: $primary;
color: white;
text-align: center;
border-radius: 6px;
left: 52%;
bottom: 120%;
padding: 15px 10px;
font-family: Nunito;
display: inline-block;
z-index: 1;
margin-bottom: 15px;
opacity: 0;
transition: opacity 0.5s;
}
.tooltipCustom .tooltiptextTopR::after {
content: '';
position: absolute;
top: 100%;
left: 50%;
margin-left: -5px;
border-width: 5px;
border-style: solid;
border-color: $primary transparent transparent transparent;
}
.tooltipCustom:hover .tooltiptextTopR {
visibility: visible;
opacity: 1;
}
/* Custom Tooltips for Block Details Page end*/

@ -0,0 +1,10 @@
/* ERC721 image block */
.erc721-image {
display: flex;
justify-content: center;
}
.erc721-image img {
height: 80px;
}
/* ERC721 image block end */

@ -4333,7 +4333,8 @@
"version": "2.1.1", "version": "2.1.1",
"resolved": false, "resolved": false,
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
"dev": true "dev": true,
"optional": true
}, },
"aproba": { "aproba": {
"version": "1.2.0", "version": "1.2.0",
@ -4798,7 +4799,8 @@
"version": "5.1.1", "version": "5.1.1",
"resolved": false, "resolved": false,
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
"dev": true "dev": true,
"optional": true
}, },
"safer-buffer": { "safer-buffer": {
"version": "2.1.2", "version": "2.1.2",
@ -4862,6 +4864,7 @@
"resolved": false, "resolved": false,
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"ansi-regex": "^2.0.0" "ansi-regex": "^2.0.0"
} }
@ -4910,13 +4913,15 @@
"version": "1.0.2", "version": "1.0.2",
"resolved": false, "resolved": false,
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"dev": true "dev": true,
"optional": true
}, },
"yallist": { "yallist": {
"version": "3.0.2", "version": "3.0.2",
"resolved": false, "resolved": false,
"integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=", "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=",
"dev": true "dev": true,
"optional": true
} }
} }
}, },

@ -8,15 +8,20 @@
<%= gettext("%{block_type} Details", block_type: block_type(@block)) %> <%= gettext("%{block_type} Details", block_type: block_type(@block)) %>
</h1> </h1>
<!-- Block Height --> <!-- Block Height -->
<h3 data-test="block_detail_number" style="width: 170px;" data-toggle="tooltip" data-placement="right" data-offset="0 0" title="" data-original-title="The block number in which transactions were recorded.">
<h3 data-test="block_detail_number" style="width: 25%;" data-toggle="tooltip" data-placement="top" title="" data-original-title="The SHA256 hash of the parent block.">
<%= if block_type(@block) == "Block" do %> <%= if block_type(@block) == "Block" do %>
<%= gettext("Block Height: %{height}", height: @block.number) %> <%= if @block.number == 0, do: "- " <> gettext("Genesis Block")%> <%= gettext("Block Height: %{height}", height: @block.number) %> <%= if @block.number == 0, do: "- " <> gettext("Genesis Block")%>
<% else %> <% else %>
<%= gettext("%{block_type} Height:", block_type: block_type(@block)) %> <%= gettext("%{block_type} Height:", block_type: block_type(@block)) %>
<%= link(@block, to: block_path(BlockScoutWeb.Endpoint, :show, @block.number)) %> <%= link(@block, to: block_path(BlockScoutWeb.Endpoint, :show, @block.number)) %>
<% end %> <% end %>
</h3> </h3>
<div class="d-flex justify-content-start text-muted block-details-row"> <div class="d-flex justify-content-start text-muted block-details-row">
<!-- # of Transactions --> <!-- # of Transactions -->
<span class="mr-4 block-detail-el"> <%= gettext "%{count} Transactions", count: @block_transaction_count %> </span> <span class="mr-4 block-detail-el"> <%= gettext "%{count} Transactions", count: @block_transaction_count %> </span>
@ -36,10 +41,13 @@
<!-- Block Hash --> <!-- Block Hash -->
<dl class="row"> <dl class="row">
<dt class="col-sm-3 text-muted"><%= gettext "Hash" %></dt> <dt class="col-sm-3 text-muted"><%= gettext "Hash" %></dt>
<dd class="col-sm-9"><a class="transaction__link" data-toggle="tooltip" data-placement="top" title="" data-original-title="The SHA256 hash of the block."><%= to_string(@block.hash) %></a></dd> <dd class="col-sm-9"><a class="transaction__link" data-toggle="tooltip" data-placement="top" title="" data-original-title="The SHA256 hash of the block."><%= to_string(@block.hash) %></a></dd>
</dl> </dl>
<%= unless @block.number == 0 do %> <%= unless @block.number == 0 do %>
<!-- Parent Hash --> <!-- Parent Hash -->
@ -123,9 +131,12 @@
<div class="card card-background-1 flex-grow-1"> <div class="card card-background-1 flex-grow-1">
<div class="card-body card-body-flex-column-space-between"> <div class="card-body card-body-flex-column-space-between">
<h2 class="card-title balance-card-title"><%= gettext "Miner" %></h2> <h2 class="card-title balance-card-title"><%= gettext "Miner" %></h2>
<div class="text-right"> <div class="text-right tooltipCustom">
<!-- Validator's Name --> <!-- Validator's Name -->
<h3 class="address-balance-text text-truncate" data-toggle="tooltip" data-offset ="0 20" data-placement="left" title="" data-original-title="Block Miner / Validator Address"> <span class="tooltiptextTopMiner"> Validator's Name</span>
<h3 class="address-balance-text text-truncate" >
<%= render BlockScoutWeb.AddressView, <%= render BlockScoutWeb.AddressView,
"_link.html", "_link.html",
address: @block.miner, address: @block.miner,
@ -135,17 +146,18 @@
</div> </div>
</div> </div>
</div> </div>
<!-- Validator Reward or Gas--> <!-- Validator Reward or Gas-->
<div class="card flex-grow-1 ml-0 ml-md-5 ml-lg-0" > <div class="card flex-grow-1 ml-0 ml-md-5 ml-lg-0" >
<div class="card-body card-body-flex-column-space-between" data-toggle="tooltip" data-offset ="0 0" data-animation="true" data-placement="left" title="" data-original-title="If Miner : Amount of distributed reward. Miners receive a static block reward + Tx fees + uncle fees. <div class="card-body card-body-flex-column-space-between">
If POA : Amount of distributed reward. Currently validators receive 1 POA token + TX fees, and the Emission fund receives 1 POA per validated block.
If xDai : Validators receive Tx fees if collected (If transactions exist in the block)">
<%= if show_reward?(@block.rewards) do %> <%= if show_reward?(@block.rewards) do %>
<h2 class="card-title balance-card-title"><%= gettext "Block Rewards" %></h2> <h2 class="card-title balance-card-title"><%= gettext "Block Rewards" %></h2>
<div class="text-right"> <div class="text-right tooltipCustom">
<span class="tooltiptextTopR"> Amount of distributed reward. Miners receive a static block reward + Tx fees + uncle fees. </span>
<%= for block_reward <- @block.rewards do %> <%= for block_reward <- @block.rewards do %>
<p class="address-current-balance"><%= block_reward_text(block_reward) %> <span class="text-muted"><%= format_wei_value(block_reward.reward, :ether) %></span></p>
<p class="address-current-balance "><%= block_reward_text(block_reward) %> <span class="text-muted"><%= format_wei_value(block_reward.reward, :ether) %></span></p>
<% end %> <% end %>
</div> </div>
<% else %> <% else %>
@ -156,6 +168,7 @@ If xDai : Validators receive Tx fees if collected (If transactions exist in the
<span class="text-muted">(<%= (Decimal.to_integer(@block.gas_used) / Decimal.to_integer(@block.gas_limit)) |> BlockScoutWeb.Cldr.Number.to_string!(format: "#.#%") %>)</span> <span class="text-muted">(<%= (Decimal.to_integer(@block.gas_used) / Decimal.to_integer(@block.gas_limit)) |> BlockScoutWeb.Cldr.Number.to_string!(format: "#.#%") %>)</span>
</h3> </h3>
<p class="address-current-balance"><%= @block.gas_limit |> BlockScoutWeb.Cldr.Number.to_string! %><%= gettext "Gas Limit" %></p> <p class="address-current-balance"><%= @block.gas_limit |> BlockScoutWeb.Cldr.Number.to_string! %><%= gettext "Gas Limit" %></p>
</div> </div>
<% end %> <% end %>
</div> </div>

@ -72,6 +72,13 @@
<div class="card-section col-md-12 col-lg-4 pl-0-md"> <div class="card-section col-md-12 col-lg-4 pl-0-md">
<div class="card card-background-1"> <div class="card card-background-1">
<div class="card-body"> <div class="card-body">
<!-- ADDITION: Need logic to display section below if @token is
ERC721 -->
<div class="erc721-image" >
<img src="/images/ether1_logo.svg" />
</div>
<!-- ADDITION END -->
<h2 class="card-title balance-card-title"><%= gettext "Total Supply" %></h2> <h2 class="card-title balance-card-title"><%= gettext "Total Supply" %></h2>
<div class="text-right"> <div class="text-right">
<h3 class="text-uppercase"> <h3 class="text-uppercase">

@ -23,4 +23,10 @@
<%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "bottom", cur_page_number: "1", show_pagination_limit: true, data_next_page_button: true, data_prev_page_button: true %> <%= render BlockScoutWeb.CommonComponentsView, "_pagination_container.html", position: "bottom", cur_page_number: "1", show_pagination_limit: true, data_next_page_button: true, data_prev_page_button: true %>
</div> </div>
</div> </div>
</section> </section>
Loading…
Cancel
Save