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
Assert.Contains($"value=\"InvoiceProcessing\" checked", s.Driver.PageSource);
Assert.Contains($"value=\"InvoiceCreated\" checked", s.Driver.PageSource);
Assert.Contains("value=\"InvoiceProcessing\" checked", s.Driver.PageSource);
Assert.Contains("value=\"InvoiceCreated\" checked", s.Driver.PageSource);
// 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.FindAlertMessage();
@ -1055,6 +1055,7 @@ namespace BTCPayServer.Tests
s.GoToStore(StoreNavPages.Webhooks);
s.Driver.FindElement(By.LinkText("Modify")).Click();
var elements = s.Driver.FindElements(By.ClassName("redeliver"));
// One worked, one failed
s.Driver.FindElement(By.ClassName("fa-times"));
s.Driver.FindElement(By.ClassName("fa-check"));

View file

@ -1,9 +1,18 @@
@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))
{
<h4>@line.Network.CryptoCode</h4>
@if (line.Status == null)
{
Title(line.Network.CryptoCode, "disabled");
<ul>
<li>The node is offline</li>
@if (line.Error != null)
@ -14,25 +23,33 @@
}
else
{
<ul>
<li>NBXplorer headers height: @line.Status.ChainHeight</li>
@if (line.Status.BitcoinStatus == null)
@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>
}
else
{
</ul>
}
else
{
Title(line.Network.CryptoCode, "disabled");
<ul>
<li>NBXplorer headers height: @line.Status.ChainHeight</li>
<li>The node is offline</li>
@if (line.Error != null)
{
<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>
@if (line.Status.BitcoinStatus.IsSynched &&
line.Status.SyncHeight.HasValue &&
@ -40,19 +57,23 @@
{
<li>NBXplorer is synchronizing... (Height: @line.Status.SyncHeight.Value)</li>
}
}
else
{
</ul>
}
else
{
Title(line.Network.CryptoCode, "enabled");
<ul>
<li>Node headers height: @line.Status.BitcoinStatus.Headers</li>
<li>Validated blocks: @line.Status.BitcoinStatus.Blocks</li>
}
</ul>
</ul>
}
@if (!line.Status.IsFullySynched && line.Status.BitcoinStatus != null)
{
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="@((int) (line.Status.BitcoinStatus.VerificationProgress * 100))"
aria-valuemin="0" aria-valuemax="100" style="width:@((int) (line.Status.BitcoinStatus.VerificationProgress * 100))%">
@((int) (line.Status.BitcoinStatus.VerificationProgress * 100))%
var percent = (int)(line.Status.BitcoinStatus.VerificationProgress * 100);
<div class="progress mb-3">
<div class="progress-bar" role="progressbar" aria-valuenow="@percent"
aria-valuemin="0" aria-valuemax="100" style="width:@(percent)%">
@percent %
</div>
</div>
}

View file

@ -6,76 +6,56 @@
<div id="syncModal" class="modal-dialog">
<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">
<h4 class="modal-title">Your nodes are synching...</h4>
<span class="fa fa-chevron-down"></span>
<h4 class="modal-title h5 fw-semibold">Your nodes are synching …</h4>
<vc:icon symbol="caret-down"/>
</a>
<div id="syncModalContent" class="collapse show">
<div class="modal-body pt-0">
<p>
Your node is synching the entire blockchain and validating the consensus rules...
</p>
<p>Your node is synching the entire blockchain and validating the consensus rules.</p>
@foreach (var provider in SyncSummaryProviders)
{
<partial name="@provider.Partial"/>
}
<p>
<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.
<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.
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 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>
<style>
#syncModal {
position: fixed;
bottom: 40px;
right: 10px;
margin: 0;
z-index: 1040;
width: 500px;
max-width: 100%;
}
#syncModal .modal-body {
max-height: 400px;
overflow-y: scroll;
}
#syncModal .fa-chevron-down {
font-size: 1em;
text-decoration: none;
transition: transform .35s;
}
#syncModal .collapsed .fa-chevron-down {
transform: rotate(-90deg);
}
</style>
#syncModal {
--outer-margin-horizontal: var(--content-padding-horizontal);
--outer-margin-vertical: 50px;
position: fixed;
z-index: 1040;
bottom: 0;
right: 0;
margin: var(--outer-margin-vertical) var(--outer-margin-horizontal);
width: 500px;
max-width: calc(100% - var(--outer-margin-horizontal) * 2);
}
#syncModal .modal-body {
/* 92px is so that the header is still displayed */
max-height: min(360px, calc(100vh - 92px - var(--outer-margin-vertical) * 2));
overflow-y: scroll;
}
#syncModal .modal-body ul {
padding-left: 2em;
}
</style>
<script>
var syncModalContent = $('#syncModalContent');
var syncModal = $('#syncModal');
if (localStorage.getItem("sync-collapsed")){
syncModalContent.removeClass("show");
}
syncModalContent.on('hidden.bs.collapse', function () {
localStorage.setItem("sync-collapsed", "true");
}).on('shown.bs.collapse', function () {
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>
const $syncModalContent = document.getElementById('syncModalContent');
const $syncModal = document.getElementById('syncModal');
if (localStorage.getItem('sync-collapsed')) {
$syncModalContent.classList.remove('show');
}
delegate('hidden.bs.collapse', '#syncModalContent', () => { localStorage.setItem('sync-collapsed', 'true'); });
delegate('shown.bs.collapse', '#syncModalContent', () => { localStorage.removeItem('sync-collapsed') });
</script>
}

View file

@ -8,12 +8,18 @@
{
@if (summary.Value != null)
{
<h4>@summary.Key</h4>
<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>
var status = summary.Value.DaemonAvailable
? summary.Value.Synced ? "enabled" : "pending"
: "disabled";
<h5 class="d-flex align-items-center fw-semibold">
<span class="me-2 btcpay-status btcpay-status--@status"></span>
@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>
}
}

View file

@ -8,12 +8,18 @@
{
@if (summary.Value != null)
{
<h4>@summary.Key</h4>
<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>
var status = summary.Value.DaemonAvailable
? summary.Value.Synced ? "enabled" : "pending"
: "disabled";
<h5 class="d-flex align-items-center fw-semibold">
<span class="me-2 btcpay-status btcpay-status--@status"></span>
@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>
}
}