Sync modal improvements (#4260)

This commit is contained in:
d11n 2022-11-02 16:55:05 +01:00 committed by GitHub
parent e56cbf0baa
commit 79717d1d64
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 106 additions and 92 deletions

View file

@ -1021,10 +1021,10 @@ namespace BTCPayServer.Tests
} }
// This one should be checked // This one should be checked
Assert.Contains($"value=\"InvoiceProcessing\" checked", s.Driver.PageSource); Assert.Contains("value=\"InvoiceProcessing\" checked", s.Driver.PageSource);
Assert.Contains($"value=\"InvoiceCreated\" checked", s.Driver.PageSource); Assert.Contains("value=\"InvoiceCreated\" checked", s.Driver.PageSource);
// This one never been checked // This one never been checked
Assert.DoesNotContain($"value=\"InvoiceReceivedPayment\" checked", s.Driver.PageSource); Assert.DoesNotContain("value=\"InvoiceReceivedPayment\" checked", s.Driver.PageSource);
s.Driver.FindElement(By.Name("update")).Click(); s.Driver.FindElement(By.Name("update")).Click();
s.FindAlertMessage(); s.FindAlertMessage();
@ -1055,6 +1055,7 @@ namespace BTCPayServer.Tests
s.GoToStore(StoreNavPages.Webhooks); s.GoToStore(StoreNavPages.Webhooks);
s.Driver.FindElement(By.LinkText("Modify")).Click(); s.Driver.FindElement(By.LinkText("Modify")).Click();
var elements = s.Driver.FindElements(By.ClassName("redeliver")); var elements = s.Driver.FindElements(By.ClassName("redeliver"));
// One worked, one failed // One worked, one failed
s.Driver.FindElement(By.ClassName("fa-times")); s.Driver.FindElement(By.ClassName("fa-times"));
s.Driver.FindElement(By.ClassName("fa-check")); s.Driver.FindElement(By.ClassName("fa-check"));

View file

@ -1,9 +1,18 @@
@inject BTCPayServer.HostedServices.NBXplorerDashboard dashboard; @inject BTCPayServer.HostedServices.NBXplorerDashboard dashboard;
@functions {
private void Title(string name, string status)
{
<h5 class="d-flex align-items-center fw-semibold">
<span class="me-2 btcpay-status btcpay-status--@status"></span>
@name
</h5>
}
}
@foreach (var line in dashboard.GetAll().Where(summary => summary.Network.ShowSyncSummary)) @foreach (var line in dashboard.GetAll().Where(summary => summary.Network.ShowSyncSummary))
{ {
<h4>@line.Network.CryptoCode</h4>
@if (line.Status == null) @if (line.Status == null)
{ {
Title(line.Network.CryptoCode, "disabled");
<ul> <ul>
<li>The node is offline</li> <li>The node is offline</li>
@if (line.Error != null) @if (line.Error != null)
@ -14,25 +23,33 @@
} }
else else
{ {
<ul> @if (line.Status.BitcoinStatus == null)
<li>NBXplorer headers height: @line.Status.ChainHeight</li> {
@if (line.Status.BitcoinStatus == null) if (line.State == BTCPayServer.HostedServices.NBXplorerState.Synching)
{ {
if (line.State == BTCPayServer.HostedServices.NBXplorerState.Synching) Title(line.Network.CryptoCode, "pending");
{ <ul>
<li>NBXplorer headers height: @line.Status.ChainHeight</li>
<li>The node is starting...</li> <li>The node is starting...</li>
} </ul>
else }
{ else
{
Title(line.Network.CryptoCode, "disabled");
<ul>
<li>NBXplorer headers height: @line.Status.ChainHeight</li>
<li>The node is offline</li> <li>The node is offline</li>
@if (line.Error != null) @if (line.Error != null)
{ {
<li>Last error: @line.Error</li> <li>Last error: @line.Error</li>
} }
} </ul>
} }
else if (line.Status.BitcoinStatus.IsSynched) }
{ else if (line.Status.BitcoinStatus.IsSynched)
{
Title(line.Network.CryptoCode, "enabled");
<ul>
<li>The node is synchronized (Height: @line.Status.BitcoinStatus.Headers)</li> <li>The node is synchronized (Height: @line.Status.BitcoinStatus.Headers)</li>
@if (line.Status.BitcoinStatus.IsSynched && @if (line.Status.BitcoinStatus.IsSynched &&
line.Status.SyncHeight.HasValue && line.Status.SyncHeight.HasValue &&
@ -40,19 +57,23 @@
{ {
<li>NBXplorer is synchronizing... (Height: @line.Status.SyncHeight.Value)</li> <li>NBXplorer is synchronizing... (Height: @line.Status.SyncHeight.Value)</li>
} }
} </ul>
else }
{ else
{
Title(line.Network.CryptoCode, "enabled");
<ul>
<li>Node headers height: @line.Status.BitcoinStatus.Headers</li> <li>Node headers height: @line.Status.BitcoinStatus.Headers</li>
<li>Validated blocks: @line.Status.BitcoinStatus.Blocks</li> <li>Validated blocks: @line.Status.BitcoinStatus.Blocks</li>
} </ul>
</ul> }
@if (!line.Status.IsFullySynched && line.Status.BitcoinStatus != null) @if (!line.Status.IsFullySynched && line.Status.BitcoinStatus != null)
{ {
<div class="progress"> var percent = (int)(line.Status.BitcoinStatus.VerificationProgress * 100);
<div class="progress-bar" role="progressbar" aria-valuenow="@((int) (line.Status.BitcoinStatus.VerificationProgress * 100))" <div class="progress mb-3">
aria-valuemin="0" aria-valuemax="100" style="width:@((int) (line.Status.BitcoinStatus.VerificationProgress * 100))%"> <div class="progress-bar" role="progressbar" aria-valuenow="@percent"
@((int) (line.Status.BitcoinStatus.VerificationProgress * 100))% aria-valuemin="0" aria-valuemax="100" style="width:@(percent)%">
@percent %
</div> </div>
</div> </div>
} }

View file

@ -6,76 +6,56 @@
<div id="syncModal" class="modal-dialog"> <div id="syncModal" class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
<a class="modal-header btn-link border-0 text-decoration-none cursor-pointer align-items-center" data-bs-toggle="collapse" data-bs-target="#syncModalContent"> <a class="modal-header btn-link border-0 text-decoration-none cursor-pointer align-items-center" data-bs-toggle="collapse" data-bs-target="#syncModalContent">
<h4 class="modal-title">Your nodes are synching...</h4> <h4 class="modal-title h5 fw-semibold">Your nodes are synching …</h4>
<span class="fa fa-chevron-down"></span> <vc:icon symbol="caret-down"/>
</a> </a>
<div id="syncModalContent" class="collapse show"> <div id="syncModalContent" class="collapse show">
<div class="modal-body pt-0"> <div class="modal-body pt-0">
<p> <p>Your node is synching the entire blockchain and validating the consensus rules.</p>
Your node is synching the entire blockchain and validating the consensus rules...
</p>
@foreach (var provider in SyncSummaryProviders) @foreach (var provider in SyncSummaryProviders)
{ {
<partial name="@provider.Partial"/> <partial name="@provider.Partial"/>
} }
<p> <p class="mb-0">
<a href="https://www.youtube.com/watch?v=OrYDehC-8TU" target="_blank" rel="noreferrer noopener">Watch this video</a> to understand the importance of blockchain synchronization. <a href="https://www.youtube.com/watch?v=OrYDehC-8TU" target="_blank" rel="noreferrer noopener">Watch this video</a>
to understand the importance of blockchain synchronization.
If you really don't want to sync and you are familiar with the command line, check
<a href="https://docs.btcpayserver.org/Docker/fastsync/" target="_blank" rel="noreferrer noopener">FastSync</a>.
</p> </p>
<p class="mb-0">If you really don't want to sync and you are familiar with the command line, check <a href="https://github.com/btcpayserver/btcpayserver-docker/blob/master/contrib/FastSync/README.md" target="_blank" rel="noreferrer noopener">FastSync</a>.</p>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<style> <style>
#syncModal { #syncModal {
position: fixed; --outer-margin-horizontal: var(--content-padding-horizontal);
bottom: 40px; --outer-margin-vertical: 50px;
right: 10px; position: fixed;
margin: 0; z-index: 1040;
z-index: 1040; bottom: 0;
width: 500px; right: 0;
max-width: 100%; margin: var(--outer-margin-vertical) var(--outer-margin-horizontal);
} width: 500px;
#syncModal .modal-body { max-width: calc(100% - var(--outer-margin-horizontal) * 2);
max-height: 400px; }
overflow-y: scroll; #syncModal .modal-body {
} /* 92px is so that the header is still displayed */
#syncModal .fa-chevron-down { max-height: min(360px, calc(100vh - 92px - var(--outer-margin-vertical) * 2));
font-size: 1em; overflow-y: scroll;
text-decoration: none; }
transition: transform .35s; #syncModal .modal-body ul {
} padding-left: 2em;
#syncModal .collapsed .fa-chevron-down { }
transform: rotate(-90deg); </style>
}
</style>
<script> <script>
var syncModalContent = $('#syncModalContent'); const $syncModalContent = document.getElementById('syncModalContent');
var syncModal = $('#syncModal'); const $syncModal = document.getElementById('syncModal');
if (localStorage.getItem("sync-collapsed")){ if (localStorage.getItem('sync-collapsed')) {
syncModalContent.removeClass("show"); $syncModalContent.classList.remove('show');
} }
syncModalContent.on('hidden.bs.collapse', function () { delegate('hidden.bs.collapse', '#syncModalContent', () => { localStorage.setItem('sync-collapsed', 'true'); });
localStorage.setItem("sync-collapsed", "true"); delegate('shown.bs.collapse', '#syncModalContent', () => { localStorage.removeItem('sync-collapsed') });
}).on('shown.bs.collapse', function () { </script>
localStorage.removeItem("sync-collapsed");
});
function handleFooterBottom() {
var footer = document.getElementsByTagName("footer")[0];
// Not all pages have a footer
if (!footer) {
return;
}
if (footer.getBoundingClientRect().top < window.innerHeight){
syncModal.stop().animate({"bottom":"40px"}, 200);
} else {
syncModal.stop().animate({"bottom":"10px"}, 200);
}
}
$(document).on("scroll", handleFooterBottom);
handleFooterBottom();
</script>
} }

View file

@ -8,12 +8,18 @@
{ {
@if (summary.Value != null) @if (summary.Value != null)
{ {
<h4>@summary.Key</h4> var status = summary.Value.DaemonAvailable
<ul > ? summary.Value.Synced ? "enabled" : "pending"
<li >Node available: @summary.Value.DaemonAvailable</li> : "disabled";
<li >Wallet available: @summary.Value.WalletAvailable</li> <h5 class="d-flex align-items-center fw-semibold">
<li >Last updated: @summary.Value.UpdatedAt</li> <span class="me-2 btcpay-status btcpay-status--@status"></span>
<li >Synced: @summary.Value.Synced (@summary.Value.CurrentHeight / @summary.Value.TargetHeight)</li> @summary.Key
</h5>
<ul>
<li>Node available: @summary.Value.DaemonAvailable</li>
<li>Wallet available: @summary.Value.WalletAvailable</li>
<li>Last updated: @summary.Value.UpdatedAt</li>
<li>Synced: @summary.Value.Synced (@summary.Value.CurrentHeight / @summary.Value.TargetHeight)</li>
</ul> </ul>
} }
} }

View file

@ -8,12 +8,18 @@
{ {
@if (summary.Value != null) @if (summary.Value != null)
{ {
<h4>@summary.Key</h4> var status = summary.Value.DaemonAvailable
<ul > ? summary.Value.Synced ? "enabled" : "pending"
<li >Node available: @summary.Value.DaemonAvailable</li> : "disabled";
<li >Wallet available: @summary.Value.WalletAvailable</li> <h5 class="d-flex align-items-center fw-semibold">
<li >Last updated: @summary.Value.UpdatedAt</li> <span class="me-2 btcpay-status btcpay-status--@status"></span>
<li >Synced: @summary.Value.Synced (@summary.Value.CurrentHeight / @summary.Value.TargetHeight)</li> @summary.Key
</h5>
<ul>
<li>Node available: @summary.Value.DaemonAvailable</li>
<li>Wallet available: @summary.Value.WalletAvailable</li>
<li>Last updated: @summary.Value.UpdatedAt</li>
<li>Synced: @summary.Value.Synced (@summary.Value.CurrentHeight / @summary.Value.TargetHeight)</li>
</ul> </ul>
} }
} }