mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-03-11 01:35:22 +01:00
Redesign Wallet UI (#3441)
* Update wallet navigation * Find matching text color for label bg color * Cleanup * Extract WalletNav component * Move PSBT link to Send and Rescan link to Settings * Update transactions view * Test fixes * Adapt invoices list actions * Show invoice actions only if there are any invoices * Link wallet name and balance to tranactions list * Move wallet related actions from list to settings * Fix main menu z-index Needs a value between fixed and the offcanvas backdrop, see https://getbootstrap.com/docs/5.1/layout/z-index/ * Update receive and send views
This commit is contained in:
parent
cd3807a3d8
commit
5c8ca15ee2
20 changed files with 400 additions and 296 deletions
|
@ -403,9 +403,9 @@ namespace BTCPayServer.Tests
|
|||
public void GoToWalletSettings(string cryptoCode = "BTC")
|
||||
{
|
||||
Driver.FindElement(By.Id($"StoreNav-Wallet{cryptoCode}")).Click();
|
||||
if (Driver.PageSource.Contains("id=\"SectionNav-Settings\""))
|
||||
if (Driver.PageSource.Contains("id=\"WalletNav-Settings\""))
|
||||
{
|
||||
Driver.FindElement(By.Id("SectionNav-Settings")).Click();
|
||||
Driver.FindElement(By.Id("WalletNav-Settings")).Click();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -565,7 +565,7 @@ namespace BTCPayServer.Tests
|
|||
Driver.Navigate().GoToUrl(new Uri(ServerUri, $"wallets/{walletId}"));
|
||||
if (navPages != WalletsNavPages.Transactions)
|
||||
{
|
||||
Driver.FindElement(By.Id($"SectionNav-{navPages}")).Click();
|
||||
Driver.FindElement(By.Id($"WalletNav-{navPages}")).Click();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -998,13 +998,13 @@ namespace BTCPayServer.Tests
|
|||
|
||||
//let's test quickly the receive wallet page
|
||||
s.Driver.FindElement(By.Id($"StoreNav-Wallet{cryptoCode}")).Click();
|
||||
s.Driver.FindElement(By.Id("SectionNav-Send")).Click();
|
||||
s.Driver.FindElement(By.Id("WalletNav-Send")).Click();
|
||||
s.Driver.FindElement(By.Id("SignTransaction")).Click();
|
||||
|
||||
//you cannot use the Sign with NBX option without saving private keys when generating the wallet.
|
||||
Assert.DoesNotContain("nbx-seed", s.Driver.PageSource);
|
||||
|
||||
s.Driver.FindElement(By.Id("SectionNav-Receive")).Click();
|
||||
s.Driver.FindElement(By.Id("WalletNav-Receive")).Click();
|
||||
//generate a receiving address
|
||||
s.Driver.FindElement(By.CssSelector("button[value=generate-new-address]")).Click();
|
||||
Assert.True(s.Driver.FindElement(By.ClassName("qr-container")).Displayed);
|
||||
|
@ -1071,20 +1071,19 @@ namespace BTCPayServer.Tests
|
|||
Assert.Contains("m/84'/1'/0'",
|
||||
s.Driver.FindElement(By.Id("AccountKeys_0__AccountKeyPath")).GetAttribute("value"));
|
||||
|
||||
s.Driver.FindElement(By.Id($"StoreNav-Wallet{cryptoCode}")).Click();
|
||||
|
||||
// Make sure we can rescan, because we are admin!
|
||||
s.Driver.FindElement(By.Id("SectionNav-Rescan")).Click();
|
||||
s.Driver.FindElement(By.Id("ActionsDropdownToggle")).Click();
|
||||
s.Driver.FindElement(By.Id("Rescan")).Click();
|
||||
Assert.Contains("The batch size make sure", s.Driver.PageSource);
|
||||
|
||||
// Check the tx sent earlier arrived
|
||||
s.Driver.FindElement(By.Id("SectionNav-Transactions")).Click();
|
||||
s.Driver.FindElement(By.Id($"StoreNav-Wallet{cryptoCode}")).Click();
|
||||
|
||||
var walletTransactionLink = s.Driver.Url;
|
||||
Assert.Contains(tx.ToString(), s.Driver.PageSource);
|
||||
|
||||
// Send to bob
|
||||
s.Driver.FindElement(By.Id("SectionNav-Send")).Click();
|
||||
s.Driver.FindElement(By.Id("WalletNav-Send")).Click();
|
||||
var bob = new Key().PubKey.Hash.GetAddress(Network.RegTest);
|
||||
SetTransactionOutput(s, 0, bob, 1);
|
||||
s.Driver.FindElement(By.Id("SignTransaction")).Click();
|
||||
|
@ -1096,7 +1095,7 @@ namespace BTCPayServer.Tests
|
|||
Assert.Equal(walletTransactionLink, s.Driver.Url);
|
||||
|
||||
s.Driver.FindElement(By.Id($"StoreNav-Wallet{cryptoCode}")).Click();
|
||||
s.Driver.FindElement(By.Id("SectionNav-Send")).Click();
|
||||
s.Driver.FindElement(By.Id("WalletNav-Send")).Click();
|
||||
|
||||
var jack = new Key().PubKey.Hash.GetAddress(Network.RegTest);
|
||||
SetTransactionOutput(s, 0, jack, 0.01m);
|
||||
|
@ -1113,7 +1112,7 @@ namespace BTCPayServer.Tests
|
|||
bip21 += "&label=Solid Snake&message=Snake? Snake? SNAAAAKE!";
|
||||
var parsedBip21 = new BitcoinUrlBuilder(bip21, Network.RegTest);
|
||||
s.Driver.FindElement(By.Id($"StoreNav-Wallet{cryptoCode}")).Click();
|
||||
s.Driver.FindElement(By.Id("SectionNav-Send")).Click();
|
||||
s.Driver.FindElement(By.Id("WalletNav-Send")).Click();
|
||||
s.Driver.FindElement(By.Id("bip21parse")).Click();
|
||||
s.Driver.SwitchTo().Alert().SendKeys(bip21);
|
||||
s.Driver.SwitchTo().Alert().Accept();
|
||||
|
|
|
@ -19,7 +19,6 @@ namespace BTCPayServer.Components.MainNav
|
|||
{
|
||||
public class MainNav : ViewComponent
|
||||
{
|
||||
private const string RootName = "Global";
|
||||
private readonly AppService _appService;
|
||||
private readonly StoreRepository _storeRepo;
|
||||
private readonly UIStoresController _storesController;
|
||||
|
|
29
BTCPayServer/Components/WalletNav/Default.cshtml
Normal file
29
BTCPayServer/Components/WalletNav/Default.cshtml
Normal file
|
@ -0,0 +1,29 @@
|
|||
@using BTCPayServer.Views.Stores
|
||||
@using BTCPayServer.Client
|
||||
@using BTCPayServer.Views.Wallets
|
||||
@using BTCPayServer.Abstractions.Extensions
|
||||
@inject BTCPayNetworkProvider _btcPayNetworkProvider
|
||||
|
||||
@model BTCPayServer.Components.WalletNav.WalletNavViewModel
|
||||
@addTagHelper *, BundlerMinifier.TagHelpers
|
||||
|
||||
<div class="d-sm-flex align-items-center justify-content-between">
|
||||
<a asp-controller="UIWallets" asp-action="WalletTransactions" asp-route-walletId="@Model.WalletId" class="unobtrusive-link">
|
||||
<h2 class="mb-1">@Model.Label</h2>
|
||||
<div class="text-muted fw-semibold">
|
||||
@Model.Balance @Model.Network.CryptoCode
|
||||
</div>
|
||||
</a>
|
||||
<div class="d-flex gap-3 mt-3 mt-sm-0" permission="@Policies.CanModifyStoreSettings">
|
||||
@if (!Model.Network.ReadonlyWallet)
|
||||
{
|
||||
<a class="btn btn-primary" asp-controller="UIWallets" asp-action="WalletSend" asp-route-walletId="@Model.WalletId" id="WalletNav-Send">Send</a>
|
||||
}
|
||||
<a class="btn btn-primary" asp-controller="UIWallets" asp-action="WalletReceive" asp-route-walletId="@Model.WalletId" id="WalletNav-Receive">Receive</a>
|
||||
<a class="btn btn-secondary @ViewData.IsActivePage(WalletsNavPages.Settings) @ViewData.IsActivePage(StoreNavPages.OnchainSettings)" asp-controller="UIStores" asp-action="WalletSettings" asp-route-cryptoCode="@Model.WalletId.CryptoCode" asp-route-storeId="@Model.WalletId.StoreId" title="Settings" id="WalletNav-Settings">
|
||||
<vc:icon symbol="settings"/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<vc:ui-extension-point location="wallet-nav" model="@Model"/>
|
56
BTCPayServer/Components/WalletNav/WalletNav.cs
Normal file
56
BTCPayServer/Components/WalletNav/WalletNav.cs
Normal file
|
@ -0,0 +1,56 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Controllers;
|
||||
using BTCPayServer.Data;
|
||||
using BTCPayServer.Models.StoreViewModels;
|
||||
using BTCPayServer.Payments;
|
||||
using BTCPayServer.Payments.Lightning;
|
||||
using BTCPayServer.Services.Apps;
|
||||
using BTCPayServer.Services.Invoices;
|
||||
using BTCPayServer.Services.Stores;
|
||||
using BTCPayServer.Services.Wallets;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
using NBitcoin;
|
||||
using NBitcoin.Secp256k1;
|
||||
|
||||
namespace BTCPayServer.Components.WalletNav
|
||||
{
|
||||
public class WalletNav : ViewComponent
|
||||
{
|
||||
private readonly BTCPayWalletProvider _walletProvider;
|
||||
private readonly UIWalletsController _walletsController;
|
||||
private readonly BTCPayNetworkProvider _networkProvider;
|
||||
|
||||
public WalletNav(
|
||||
BTCPayWalletProvider walletProvider,
|
||||
BTCPayNetworkProvider networkProvider,
|
||||
UIWalletsController walletsController)
|
||||
{
|
||||
_walletProvider = walletProvider;
|
||||
_networkProvider = networkProvider;
|
||||
_walletsController = walletsController;
|
||||
}
|
||||
|
||||
public async Task<IViewComponentResult> InvokeAsync(WalletId walletId)
|
||||
{
|
||||
var store = ViewContext.HttpContext.GetStoreData();
|
||||
var network = _networkProvider.GetNetwork<BTCPayNetwork>(walletId.CryptoCode);
|
||||
var wallet = _walletProvider.GetWallet(network);
|
||||
var derivation = store.GetDerivationSchemeSettings(_networkProvider, walletId.CryptoCode);
|
||||
var balance = await _walletsController.GetBalanceString(wallet, derivation.AccountDerivation);
|
||||
|
||||
var vm = new WalletNavViewModel
|
||||
{
|
||||
WalletId = walletId,
|
||||
Network = network,
|
||||
Balance = balance,
|
||||
Label = derivation.Label ?? $"{store.StoreName} {walletId.CryptoCode} Wallet"
|
||||
};
|
||||
|
||||
return View(vm);
|
||||
}
|
||||
}
|
||||
}
|
10
BTCPayServer/Components/WalletNav/WalletNavViewModel.cs
Normal file
10
BTCPayServer/Components/WalletNav/WalletNavViewModel.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
namespace BTCPayServer.Components.WalletNav
|
||||
{
|
||||
public class WalletNavViewModel
|
||||
{
|
||||
public WalletId WalletId { get; set; }
|
||||
public BTCPayNetwork Network { get; set; }
|
||||
public string Label { get; set; }
|
||||
public string Balance { get; set; }
|
||||
}
|
||||
}
|
|
@ -1057,7 +1057,7 @@ namespace BTCPayServer.Controllers
|
|||
}
|
||||
}
|
||||
|
||||
private static async Task<string> GetBalanceString(BTCPayWallet wallet, DerivationStrategyBase derivationStrategy)
|
||||
internal async Task<string> GetBalanceString(BTCPayWallet wallet, DerivationStrategyBase derivationStrategy)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace BTCPayServer.Services.Labels
|
|||
|
||||
public string Text { get; internal set; }
|
||||
public string Color { get; internal set; }
|
||||
public string TextColor { get; internal set; }
|
||||
public string Link { get; internal set; }
|
||||
public string Tooltip { get; internal set; }
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using Amazon.Util.Internal.PlatformServices;
|
||||
using BTCPayServer.Client.Models;
|
||||
using BTCPayServer.Data;
|
||||
|
@ -41,12 +42,13 @@ namespace BTCPayServer.Services.Labels
|
|||
private ColoredLabel CreateLabel(LabelData uncoloredLabel, string color, HttpRequest request)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(uncoloredLabel);
|
||||
color = color ?? DefaultColor;
|
||||
color ??= DefaultColor;
|
||||
|
||||
ColoredLabel coloredLabel = new ColoredLabel()
|
||||
ColoredLabel coloredLabel = new ColoredLabel
|
||||
{
|
||||
Text = uncoloredLabel.Text,
|
||||
Color = color
|
||||
Color = color,
|
||||
TextColor = TextColor(color)
|
||||
};
|
||||
if (uncoloredLabel is ReferenceLabel refLabel)
|
||||
{
|
||||
|
@ -90,5 +92,14 @@ namespace BTCPayServer.Services.Labels
|
|||
}
|
||||
return coloredLabel;
|
||||
}
|
||||
|
||||
private string TextColor(string bgColor)
|
||||
{
|
||||
int nThreshold = 105;
|
||||
var bg = ColorTranslator.FromHtml(bgColor);
|
||||
int bgDelta = Convert.ToInt32((bg.R * 0.299) + (bg.G * 0.587) + (bg.B * 0.114));
|
||||
Color color = (255 - bgDelta < nThreshold) ? Color.Black : Color.White;
|
||||
return ColorTranslator.ToHtml(color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
}
|
||||
|
||||
/* pull mass action form up, so that it is besides the search form */
|
||||
@@media (min-width: 992px) {
|
||||
@@media (min-width: 1200px) {
|
||||
#MassAction {
|
||||
margin-top: -4rem;
|
||||
}
|
||||
|
@ -267,7 +267,7 @@
|
|||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<form class="col-lg-6 col-xl-8 mb-4" asp-action="ListInvoices" asp-route-storeId="@Model.StoreId" method="get">
|
||||
<form class="@(Model.Total > 0 ? "col-xl-7 col-xxl-8 " : "")mb-4" asp-action="ListInvoices" asp-route-storeId="@Model.StoreId" method="get">
|
||||
<input type="hidden" asp-for="Count" />
|
||||
<input asp-for="TimezoneOffset" type="hidden" />
|
||||
<div class="input-group">
|
||||
|
@ -302,38 +302,38 @@
|
|||
<span asp-validation-for="SearchTerm" class="text-danger"></span>
|
||||
</form>
|
||||
|
||||
<form method="post" id="MassAction" asp-action="MassAction" class="">
|
||||
<div class="d-inline-flex align-items-center pb-2 float-lg-end mb-2">
|
||||
<input type="hidden" name="storeId" value="@Model.StoreId" />
|
||||
<a href="https://docs.btcpayserver.org/Accounting/" class="ms-2 ms-lg-0 me-lg-2 order-1 order-lg-0" target="_blank" rel="noreferrer noopener">
|
||||
<span class="fa fa-question-circle-o text-secondary" title="More information..."></span>
|
||||
</a>
|
||||
<span class="me-2">
|
||||
<button class="btn btn-secondary dropdown-toggle mb-1" type="button" id="ActionsDropdownToggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
Actions
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="ActionsDropdownToggle">
|
||||
<button type="submit" class="dropdown-item" name="command" value="archive" id="ActionsDropdownArchive"><i class="fa fa-archive"></i> Archive</button>
|
||||
@if (Model.IncludeArchived)
|
||||
{
|
||||
<button type="submit" asp-action="MassAction" class="dropdown-item" name="command" value="unarchive" id="ActionsDropdownUnarchive"><i class="fa fa-archive"></i> Unarchive</button>
|
||||
}
|
||||
<button id="BumpFee" type="submit" permission="@Policies.CanModifyStoreSettings" class="dropdown-item" name="command" value="cpfp">Bump fee</button>
|
||||
</div>
|
||||
</span>
|
||||
<span>
|
||||
<a class="btn btn-secondary dropdown-toggle mb-1" href="#" role="button" id="ExportDropdownToggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
Export
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="ExportDropdownToggle">
|
||||
<a asp-action="Export" asp-route-timezoneoffset="0" asp-route-format="csv" asp-route-searchTerm="@Model.SearchTerm" class="dropdown-item export-link" target="_blank">CSV</a>
|
||||
<a asp-action="Export" asp-route-timezoneoffset="0" asp-route-format="json" asp-route-searchTerm="@Model.SearchTerm" class="dropdown-item export-link" target="_blank">JSON</a>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
<div style="clear:both"></div>
|
||||
@if (Model.Total > 0)
|
||||
{
|
||||
@if (Model.Total > 0)
|
||||
{
|
||||
<form method="post" id="MassAction" asp-action="MassAction" class="">
|
||||
<div class="d-inline-flex align-items-center pb-2 float-xl-end mb-2 gap-3">
|
||||
<input type="hidden" name="storeId" value="@Model.StoreId" />
|
||||
<span class="order-xl-1">
|
||||
<button class="btn btn-secondary dropdown-toggle mb-1" type="button" id="ActionsDropdownToggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
Actions
|
||||
</button>
|
||||
<div class="dropdown-menu dropdown-menu-xl-end" aria-labelledby="ActionsDropdownToggle">
|
||||
<button type="submit" class="dropdown-item" name="command" value="archive" id="ActionsDropdownArchive">Archive</button>
|
||||
@if (Model.IncludeArchived)
|
||||
{
|
||||
<button type="submit" asp-action="MassAction" class="dropdown-item" name="command" value="unarchive" id="ActionsDropdownUnarchive">Unarchive</button>
|
||||
}
|
||||
<button id="BumpFee" type="submit" permission="@Policies.CanModifyStoreSettings" class="dropdown-item" name="command" value="cpfp">Bump fee</button>
|
||||
</div>
|
||||
</span>
|
||||
<span class="d-inline-flex align-items-center gap-3">
|
||||
<a class="btn btn-secondary dropdown-toggle mb-1 order-xl-1" href="#" role="button" id="ExportDropdownToggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
Export
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="ExportDropdownToggle">
|
||||
<a asp-action="Export" asp-route-timezoneoffset="0" asp-route-format="csv" asp-route-searchTerm="@Model.SearchTerm" class="dropdown-item export-link" target="_blank">CSV</a>
|
||||
<a asp-action="Export" asp-route-timezoneoffset="0" asp-route-format="json" asp-route-searchTerm="@Model.SearchTerm" class="dropdown-item export-link" target="_blank">JSON</a>
|
||||
</div>
|
||||
<a href="https://docs.btcpayserver.org/Accounting/" target="_blank" rel="noreferrer noopener">
|
||||
<span class="fa fa-question-circle-o text-secondary" title="More information..."></span>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
<div style="clear:both"></div>
|
||||
<div class="table-responsive">
|
||||
<table id="invoices" class="table table-hover">
|
||||
<thead>
|
||||
|
@ -452,11 +452,12 @@
|
|||
</div>
|
||||
|
||||
<vc:pager view-model="Model" />
|
||||
}
|
||||
else
|
||||
{
|
||||
<p class="text-secondary mt-3">
|
||||
There are no invoices matching your criteria.
|
||||
</p>
|
||||
}
|
||||
</form>
|
||||
|
||||
</form>
|
||||
}
|
||||
else
|
||||
{
|
||||
<p class="text-secondary mt-3">
|
||||
There are no invoices matching your criteria.
|
||||
</p>
|
||||
}
|
||||
|
|
|
@ -19,48 +19,56 @@
|
|||
<h3 class="mb-3">@ViewData["Title"]</h3>
|
||||
<div class="mb-3 d-flex align-items-center">
|
||||
<span title="@Model.Source" data-bs-toggle="tooltip" class="me-3">@(Model.IsHotWallet ? "Hot wallet" : "Watch-only wallet")</span>
|
||||
|
||||
<form method="get" asp-action="DeleteWallet" asp-route-storeId="@Model.StoreId" asp-route-cryptoCode="@Model.CryptoCode" class="d-inline">
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-secondary dropdown-toggle mb-1" type="button" id="ActionsDropdownToggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
Actions
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="ActionsDropdownToggle">
|
||||
@if (Model.NBXSeedAvailable)
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-secondary dropdown-toggle" type="button" id="ActionsDropdownToggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
Actions
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="ActionsDropdownToggle">
|
||||
<a class="dropdown-item" asp-controller="UIWallets" asp-action="WalletRescan" asp-route-walletId="@Model.WalletId" id="Rescan">Rescan wallet for missing transactions</a>
|
||||
<form method="post" asp-controller="UIWallets" asp-action="WalletActions" asp-route-walletId="@Model.WalletId">
|
||||
<button name="command" type="submit" class="dropdown-item" value="prune">Prune old transactions from history</button>
|
||||
@if (User.IsInRole(Roles.ServerAdmin))
|
||||
{
|
||||
<a asp-action="WalletSeed" asp-route-storeId="@Model.StoreId" asp-route-cryptoCode="@Model.CryptoCode" class="dropdown-item" id="ViewSeed">View seed</a>
|
||||
<button name="command" type="submit" class="dropdown-item" value="clear">Clear all transactions from history</button>
|
||||
}
|
||||
@if (Model.UriScheme == "bitcoin")
|
||||
{
|
||||
<button type="button" class="dropdown-item" id="RegisterWallet" data-store="@Model.StoreName" data-scheme="@Model.UriScheme" data-url="@Url.Action("WalletSend", "UIWallets", new {walletId = Model.WalletId, bip21 = "%s"})" hidden>Register wallet for payment links</button>
|
||||
}
|
||||
<a asp-controller="UIStores" asp-action="ReplaceWallet" asp-route-storeId="@Model.StoreId" asp-route-cryptoCode="@Model.CryptoCode"
|
||||
id="ChangeWalletLink"
|
||||
class="dropdown-item"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#ConfirmModal"
|
||||
data-title="Replace @Model.CryptoCode wallet"
|
||||
data-description="@ViewData["ReplaceDescription"]"
|
||||
data-confirm="Setup new wallet"
|
||||
data-confirm-input="REPLACE">
|
||||
Replace wallet
|
||||
</a>
|
||||
</form>
|
||||
@if (Model.UriScheme == "bitcoin")
|
||||
{
|
||||
<button type="button" class="dropdown-item" id="RegisterWallet" data-store="@Model.StoreName" data-scheme="@Model.UriScheme" data-url="@Url.Action("WalletSend", "UIWallets", new {walletId = Model.WalletId, bip21 = "%s"})" hidden>Register wallet for payment links</button>
|
||||
}
|
||||
<div class="dropdown-divider"></div>
|
||||
@if (Model.NBXSeedAvailable)
|
||||
{
|
||||
<a asp-action="WalletSeed" asp-route-storeId="@Model.StoreId" asp-route-cryptoCode="@Model.CryptoCode" class="dropdown-item" id="ViewSeed">View seed</a>
|
||||
}
|
||||
<a asp-controller="UIStores" asp-action="ReplaceWallet" asp-route-storeId="@Model.StoreId" asp-route-cryptoCode="@Model.CryptoCode"
|
||||
id="ChangeWalletLink"
|
||||
class="dropdown-item"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#ConfirmModal"
|
||||
data-title="Replace @Model.CryptoCode wallet"
|
||||
data-description="@ViewData["ReplaceDescription"]"
|
||||
data-confirm="Setup new wallet"
|
||||
data-confirm-input="REPLACE">
|
||||
Replace wallet
|
||||
</a>
|
||||
<form method="get" asp-action="DeleteWallet" asp-route-storeId="@Model.StoreId" asp-route-cryptoCode="@Model.CryptoCode" class="d-inline">
|
||||
<button type="submit"
|
||||
id="Delete"
|
||||
class="dropdown-item"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#ConfirmModal"
|
||||
data-title="Remove @Model.CryptoCode wallet"
|
||||
data-description="@ViewData["RemoveDescription"]"
|
||||
data-confirm="Remove"
|
||||
data-confirm-input="REMOVE">Remove wallet</button>
|
||||
</div>
|
||||
id="Delete"
|
||||
class="dropdown-item"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#ConfirmModal"
|
||||
data-title="Remove @Model.CryptoCode wallet"
|
||||
data-description="@ViewData["RemoveDescription"]"
|
||||
data-confirm="Remove"
|
||||
data-confirm-input="REMOVE">Remove wallet</button>
|
||||
</form>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form method="post" asp-action="UpdateWalletSettings" asp-route-storeId="@Model.StoreId" asp-route-cryptoCode="@Model.CryptoCode">
|
||||
<div class="form-group">
|
||||
<div class="form-group my-4">
|
||||
<div class="d-flex align-items-center">
|
||||
<input asp-for="Enabled" type="checkbox" class="btcpay-toggle me-2"/>
|
||||
<label asp-for="Enabled" class="form-label mb-0 me-1"></label>
|
||||
|
|
|
@ -13,18 +13,17 @@
|
|||
|
||||
<div class="row no-gutters">
|
||||
<div class="col-xl-8 col-xxl-constrain">
|
||||
<form method="post" asp-action="WalletReceive" class="text-center">
|
||||
<form method="post" asp-action="WalletReceive">
|
||||
@if (string.IsNullOrEmpty(Model.Address))
|
||||
{
|
||||
<h3 class="mb-3">@ViewData["Title"]</h3>
|
||||
<button id="generateButton" class="btn btn-lg btn-primary" type="submit" name="command" value="generate-new-address">Generate @Model.CryptoCode address</button>
|
||||
<button id="generateButton" class="btn btn-primary" type="submit" name="command" value="generate-new-address">Generate next available @Model.CryptoCode address</button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<h3 class="mb-4">@Model.CryptoCode Address</h3>
|
||||
<noscript>
|
||||
<div class="m-sm-0 p-sm-0">
|
||||
<div class="form-group">
|
||||
<div class="form-group">
|
||||
<input type="text" class="form-control " readonly="readonly" asp-for="Address" id="address"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
@ -51,7 +50,7 @@
|
|||
<vc:qr-code data="@Model.Address"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="nav justify-content-center">
|
||||
<div class="nav">
|
||||
<a class="btcpay-pill active" data-bs-toggle="tab" href="#link-tab">Link</a>
|
||||
<a class="btcpay-pill" data-bs-toggle="tab" href="#address-tab">Address</a>
|
||||
</div>
|
||||
|
@ -59,13 +58,17 @@
|
|||
<div class="form-group">
|
||||
<div class="input-group" data-clipboard="@Model.Address">
|
||||
<input type="text" class="form-control" style="cursor:copy" readonly="readonly" value="@Model.Address" id="address"/>
|
||||
<button type="button" class="input-group-text btn btn-outline-secondary" style="width:10em;" data-clipboard-confirm>Copy address</button>
|
||||
<button type="button" class="input-group-text btn btn-outline-secondary p-2" style="width:7em;" data-clipboard-confirm>
|
||||
<vc:icon symbol="copy"/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="input-group" data-clipboard="@Model.PaymentLink">
|
||||
<input type="text" class="form-control" style="cursor:copy" readonly="readonly" value="@Model.PaymentLink" id="payment-link"/>
|
||||
<button type="button" class="btn btn-outline-secondary" style="width:10em;" data-clipboard-confirm>Copy link</button>
|
||||
<button type="button" class="btn btn-outline-secondary p-2" style="width:7em;" data-clipboard-confirm>
|
||||
<vc:icon symbol="copy"/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-4">
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
|
||||
<div class="row">
|
||||
<div class="col-xl-8 col-xxl-constrain @(!Model.InputSelection && Model.Outputs.Count == 1 ? "transaction-output-form" : "")">
|
||||
<h3 class="mb-3">@ViewData["Title"]</h3>
|
||||
<form method="post" asp-action="WalletSend" asp-route-walletId="@walletId">
|
||||
<input type="hidden" asp-for="InputSelection" />
|
||||
<input type="hidden" asp-for="FiatDivisibility" />
|
||||
|
@ -229,10 +228,11 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group d-flex mt-2">
|
||||
<div class="form-group d-flex gap-3 mt-2">
|
||||
<button type="submit" id="SignTransaction" name="command" value="sign" class="btn btn-primary">Sign transaction</button>
|
||||
<button type="button" id="bip21parse" class="ms-3 btn btn-secondary" title="Paste BIP21/Address"><i class="fa fa-paste"></i></button>
|
||||
<button type="button" id="scanqrcode" class="ms-3 btn btn-secondary only-for-js" data-bs-toggle="modal" data-bs-target="#scanModal" title="Scan BIP21/Address with camera"><i class="fa fa-camera"></i></button>
|
||||
<a class="btn btn-secondary" asp-controller="UIWallets" asp-action="WalletPSBT" asp-route-walletId="@walletId" id="PSBT">PSBT</a>
|
||||
<button type="button" id="bip21parse" class="btn btn-secondary" title="Paste BIP21/Address"><i class="fa fa-paste"></i></button>
|
||||
<button type="button" id="scanqrcode" class="btn btn-secondary only-for-js" data-bs-toggle="modal" data-bs-target="#scanModal" title="Scan BIP21/Address with camera"><i class="fa fa-camera"></i></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
@@media (min-width: 990px) {
|
||||
.smMaxWidth {
|
||||
max-width: 250px;
|
||||
max-width: 200px;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,187 +76,174 @@
|
|||
</script>
|
||||
}
|
||||
|
||||
<div class="d-flex align-items-center justify-content-between mb-3">
|
||||
<h3 class="mb-0">@ViewData["Title"]</h3>
|
||||
<form id="WalletActions" method="post" asp-action="WalletActions" asp-route-walletId="@Context.GetRouteValue("walletId")">
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-secondary dropdown-toggle mb-1" type="button" id="ActionsDropdownToggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
Actions
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="ActionsDropdownToggle">
|
||||
<button id="BumpFee" name="command" type="submit" class="dropdown-item" value="cpfp">Bump fee (CPFP)</button>
|
||||
<a asp-action="WalletRescan" asp-route-walletId="@Context.GetRouteValue("walletId")" class="dropdown-item">Rescan wallet for missing transactions</a>
|
||||
<button name="command" type="submit" class="dropdown-item" value="prune">Prune old transactions from history</button>
|
||||
@if (User.IsInRole(Roles.ServerAdmin))
|
||||
{
|
||||
<button name="command" type="submit" class="dropdown-item" value="clear">Clear all transactions from history</button>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<p class="mb-0">
|
||||
If BTCPay Server shows you an invalid balance, <a asp-action="WalletRescan" asp-route-walletId="@Context.GetRouteValue("walletId")">rescan your wallet</a>.
|
||||
<br/>
|
||||
If some transactions appear in BTCPay Server, but are missing in another wallet, <a href="https://docs.btcpayserver.org/FAQ/Wallet/#missing-payments-in-my-software-or-hardware-wallet" rel="noreferrer noopener">follow these instructions</a>.
|
||||
</p>
|
||||
|
||||
@if (Model.Transactions.Any())
|
||||
{
|
||||
@if (Model.Labels.Any())
|
||||
{
|
||||
<div class="row mt-4">
|
||||
<div class="col-md-12">
|
||||
<div class="d-flex flex-row align-items-center flex-wrap card card-body px-3 py-2">
|
||||
<span class="me-2">Filter by label:</span>
|
||||
<div class="d-flex align-items-center gap-3 mb-2">
|
||||
@if (Model.Labels.Any())
|
||||
{
|
||||
<div class="input-group">
|
||||
<span class="input-group-text">Filter</span>
|
||||
<div class="form-control d-flex flex-wrap gap-2 align-items-center">
|
||||
@foreach (var label in Model.Labels)
|
||||
{
|
||||
<a asp-route-labelFilter="@label.Text" class="badge me-2 my-1 position-relative text-white d-block" style="background-color: @label.Color;">@label.Text</a>
|
||||
<a asp-route-labelFilter="@label.Text" class="badge position-relative text-white flex-grow-0" style="background-color:@label.Color;color:@label.TextColor !important;">@label.Text</a>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div class="dropdown ms-auto">
|
||||
<button class="btn btn-secondary dropdown-toggle" type="button" id="ActionsDropdownToggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
Actions
|
||||
</button>
|
||||
<div class="dropdown-menu dropdown-menu-end" aria-labelledby="ActionsDropdownToggle">
|
||||
<form id="WalletActions" method="post" asp-action="WalletActions" asp-route-walletId="@walletId">
|
||||
<button id="BumpFee" name="command" type="submit" class="dropdown-item" value="cpfp">Bump fee (CPFP)</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div class="table-responsive-md">
|
||||
<table class="table table-hover">
|
||||
<thead class="thead-inverse">
|
||||
<tr>
|
||||
<th style="width:2rem;" class="only-for-js">
|
||||
<input id="selectAllCheckbox" type="checkbox" class="form-check-input" />
|
||||
</th>
|
||||
<th style="min-width: 90px;" class="col-md-auto">
|
||||
Date
|
||||
<a id="switchTimeFormat" href="#">
|
||||
<span class="fa fa-clock-o" title="Switch date format"></span>
|
||||
</a>
|
||||
</th>
|
||||
<th class="text-start">Label</th>
|
||||
<th>Transaction Id</th>
|
||||
<th class="text-end">Amount</th>
|
||||
<th class="text-end"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var transaction in Model.Transactions)
|
||||
{
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col table-responsive-md">
|
||||
<table class="table table-hover">
|
||||
<thead class="thead-inverse">
|
||||
<tr>
|
||||
<td class="only-for-js">
|
||||
<input name="selectedTransactions" type="checkbox" class="selector form-check-input" form="WalletActions" value="@transaction.Id" />
|
||||
</td>
|
||||
<td>
|
||||
<span class="switchTimeFormat" data-switch="@transaction.Timestamp.ToTimeAgo()">
|
||||
@transaction.Timestamp.ToBrowserDate()
|
||||
</span>
|
||||
</td>
|
||||
<td class="text-start">
|
||||
@foreach (var label in transaction.Labels)
|
||||
{
|
||||
<div class="badge-container">
|
||||
<div
|
||||
class="badge transactionLabel position-relative text-white d-block"
|
||||
style="background-color: @label.Color; padding-right: 16px; z-index: 1;"
|
||||
data-bs-toggle="tooltip"
|
||||
title="@label.Tooltip">
|
||||
<a asp-route-labelFilter="@label.Text" class="text-white">@label.Text</a>
|
||||
<th style="width:2rem;" class="only-for-js">
|
||||
<input id="selectAllCheckbox" type="checkbox" class="form-check-input"/>
|
||||
</th>
|
||||
<th style="min-width: 90px;" class="col-md-auto">
|
||||
Date
|
||||
<a id="switchTimeFormat" href="#">
|
||||
<span class="fa fa-clock-o" title="Switch date format"></span>
|
||||
</a>
|
||||
</th>
|
||||
<th class="text-start">Label</th>
|
||||
<th>Transaction Id</th>
|
||||
<th class="text-end">Amount</th>
|
||||
<th class="text-end"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var transaction in Model.Transactions)
|
||||
{
|
||||
<tr>
|
||||
<td class="only-for-js">
|
||||
<input name="selectedTransactions" type="checkbox" class="selector form-check-input" form="WalletActions" value="@transaction.Id"/>
|
||||
</td>
|
||||
<td>
|
||||
<span class="switchTimeFormat" data-switch="@transaction.Timestamp.ToTimeAgo()">
|
||||
@transaction.Timestamp.ToBrowserDate()
|
||||
</span>
|
||||
</td>
|
||||
<td class="text-start">
|
||||
@foreach (var label in transaction.Labels)
|
||||
{
|
||||
<div class="badge-container">
|
||||
<div
|
||||
class="badge transactionLabel position-relative text-white d-block"
|
||||
style="background-color:@label.Color;padding-right: 16px; z-index: 1;"
|
||||
data-bs-toggle="tooltip"
|
||||
title="@label.Tooltip">
|
||||
<a asp-route-labelFilter="@label.Text" style="color:@label.TextColor !important;">@label.Text</a>
|
||||
|
||||
<form
|
||||
asp-route-walletId="@Context.GetRouteValue("walletId")"
|
||||
asp-action="ModifyTransaction"
|
||||
method="post"
|
||||
class="removeTransactionLabelForm">
|
||||
<form
|
||||
asp-route-walletId="@Context.GetRouteValue("walletId")"
|
||||
asp-action="ModifyTransaction"
|
||||
method="post"
|
||||
class="removeTransactionLabelForm">
|
||||
<input type="hidden" name="transactionId" value="@transaction.Id"/>
|
||||
<button
|
||||
name="removelabel"
|
||||
style="color: @label.Color; filter: brightness(0.5);"
|
||||
type="submit"
|
||||
value="@label.Text">
|
||||
<span class="fa fa-close"></span>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
@if (!string.IsNullOrEmpty(label.Link))
|
||||
{
|
||||
<a href="@label.Link" target="_blank" class="badge transaction-details-icon" style="background-color: @label.Color; filter: brightness(1.1);" rel="noreferrer noopener">
|
||||
<span class="fa fa-info-circle" title="Transaction details" style="color: @label.Color; filter: brightness(0.5);">
|
||||
<span class="visually-hidden">Transaction details</span>
|
||||
</span>
|
||||
</a>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</td>
|
||||
<td class="smMaxWidth text-truncate @(transaction.IsConfirmed ? "" : "unconf")">
|
||||
<a href="@transaction.Link" target="_blank" rel="noreferrer noopener">
|
||||
@transaction.Id
|
||||
</a>
|
||||
</td>
|
||||
@if (transaction.Positive)
|
||||
{
|
||||
<td class="text-end text-success">@transaction.Balance</td>
|
||||
}
|
||||
else
|
||||
{
|
||||
<td class="text-end text-danger">@transaction.Balance</td>
|
||||
}
|
||||
<td class="text-end">
|
||||
<div class="dropstart d-inline-block">
|
||||
<span class="fa fa-tags cursor-pointer" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></span>
|
||||
<div class="dropdown-menu">
|
||||
<form asp-action="ModifyTransaction" method="post"
|
||||
asp-route-walletId="@Context.GetRouteValue("walletId")">
|
||||
<input type="hidden" name="transactionId" value="@transaction.Id"/>
|
||||
<button
|
||||
name="removelabel"
|
||||
style="color: @label.Color; filter: brightness(0.5);"
|
||||
type="submit"
|
||||
value="@label.Text">
|
||||
<span class="fa fa-close"></span>
|
||||
</button>
|
||||
<div class="input-group input-group-sm p-2">
|
||||
<input name="addlabel" placeholder="Label name" maxlength="20" type="text" class="form-control form-control-sm"/>
|
||||
<button type="submit" class="btn btn-primary btn-sm"><span class="fa fa-plus"></span></button>
|
||||
</div>
|
||||
@if (Model.Labels.Count > 0)
|
||||
{
|
||||
<div class="dropdown-divider"></div>
|
||||
<div class="px-2">
|
||||
@foreach (var label in Model.Labels)
|
||||
{
|
||||
@if (transaction.Labels.Contains(label))
|
||||
{
|
||||
<button name="removelabel" class="bg-transparent border-0 p-0" type="submit" value="@label.Text"><span class="badge" style="display:block;background-color:@label.Color;color:white;text-align:left;"><span class="fa fa-check"></span> @label.Text</span></button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<button name="addlabelclick" class="bg-transparent border-0 p-0" type="submit" value="@label.Text"><span class="badge" style="display:block;background-color:@label.Color;color:white;text-align:left;">@label.Text</span></button>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</form>
|
||||
</div>
|
||||
@if (!string.IsNullOrEmpty(label.Link))
|
||||
</div>
|
||||
<div class="dropstart d-inline-block">
|
||||
@if (string.IsNullOrEmpty(transaction.Comment))
|
||||
{
|
||||
<a href="@label.Link" target="_blank" class="badge transaction-details-icon" style="background-color: @label.Color; filter: brightness(1.1);" rel="noreferrer noopener">
|
||||
<span class="fa fa-info-circle" title="Transaction details" style="color: @label.Color; filter: brightness(0.5);">
|
||||
<span class="visually-hidden">Transaction details</span>
|
||||
</span>
|
||||
</a>
|
||||
<span class="fa fa-comment cursor-pointer" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></span>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</td>
|
||||
<td class="smMaxWidth text-truncate @(transaction.IsConfirmed ? "" : "unconf")">
|
||||
<a href="@transaction.Link" target="_blank" rel="noreferrer noopener">
|
||||
@transaction.Id
|
||||
</a>
|
||||
</td>
|
||||
@if (transaction.Positive)
|
||||
{
|
||||
<td class="text-end text-success">@transaction.Balance</td>
|
||||
}
|
||||
else
|
||||
{
|
||||
<td class="text-end text-danger">@transaction.Balance</td>
|
||||
}
|
||||
<td class="text-end">
|
||||
<div class="dropstart d-inline-block">
|
||||
<span class="fa fa-tags cursor-pointer" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></span>
|
||||
<div class="dropdown-menu">
|
||||
<form asp-action="ModifyTransaction" method="post"
|
||||
asp-route-walletId="@Context.GetRouteValue("walletId")">
|
||||
<input type="hidden" name="transactionId" value="@transaction.Id"/>
|
||||
<div class="input-group input-group-sm p-2">
|
||||
<input name="addlabel" placeholder="Label name" maxlength="20" type="text" class="form-control form-control-sm"/>
|
||||
<button type="submit" class="btn btn-primary btn-sm"><span class="fa fa-plus"></span></button>
|
||||
</div>
|
||||
@if (Model.Labels.Count > 0)
|
||||
{
|
||||
<div class="dropdown-divider"></div>
|
||||
<div class="px-2">
|
||||
@foreach (var label in Model.Labels)
|
||||
{
|
||||
@if (transaction.Labels.Contains(label))
|
||||
{
|
||||
<button name="removelabel" class="bg-transparent border-0 p-0" type="submit" value="@label.Text"><span class="badge" style="display:block;background-color:@label.Color;color:white;text-align:left;"><span class="fa fa-check"></span> @label.Text</span></button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<button name="addlabelclick" class="bg-transparent border-0 p-0" type="submit" value="@label.Text"><span class="badge" style="display:block;background-color:@label.Color;color:white;text-align:left;">@label.Text</span></button>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
<span class="fa fa-commenting cursor-pointer" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></span>
|
||||
}
|
||||
<div class="dropdown-menu">
|
||||
<form asp-action="ModifyTransaction" method="post"
|
||||
asp-route-walletId="@Context.GetRouteValue("walletId")">
|
||||
<input type="hidden" name="transactionId" value="@transaction.Id"/>
|
||||
<div class="input-group p-2">
|
||||
<textarea name="addcomment" maxlength="200" rows="2" cols="20" class="form-control form-control-sm p-1">@transaction.Comment</textarea>
|
||||
</div>
|
||||
}
|
||||
</form>
|
||||
<div class="p-2">
|
||||
<button type="submit" class="btn btn-primary btn-sm">Save comment</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dropstart d-inline-block">
|
||||
@if (string.IsNullOrEmpty(transaction.Comment))
|
||||
{
|
||||
<span class="fa fa-comment cursor-pointer" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span class="fa fa-commenting cursor-pointer" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></span>
|
||||
}
|
||||
<div class="dropdown-menu">
|
||||
<form asp-action="ModifyTransaction" method="post"
|
||||
asp-route-walletId="@Context.GetRouteValue("walletId")">
|
||||
<input type="hidden" name="transactionId" value="@transaction.Id"/>
|
||||
<div class="input-group p-2">
|
||||
<textarea name="addcomment" maxlength="200" rows="2" cols="20" class="form-control form-control-sm p-1">@transaction.Comment</textarea>
|
||||
</div>
|
||||
<div class="p-2">
|
||||
<button type="submit" class="btn btn-primary btn-sm">Save comment</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<vc:pager view-model="Model"/>
|
||||
}
|
||||
|
@ -266,3 +253,9 @@ else
|
|||
There are no transactions yet.
|
||||
</p>
|
||||
}
|
||||
|
||||
<p class="mt-4 mb-0">
|
||||
If BTCPay Server shows you an invalid balance, <a asp-action="WalletRescan" asp-route-walletId="@Context.GetRouteValue("walletId")">rescan your wallet</a>.
|
||||
<br/>
|
||||
If some transactions appear in BTCPay Server, but are missing in another wallet, <a href="https://docs.btcpayserver.org/FAQ/Wallet/#missing-payments-in-my-software-or-hardware-wallet" rel="noreferrer noopener">follow these instructions</a>.
|
||||
</p>
|
||||
|
|
|
@ -1,27 +1,15 @@
|
|||
@using BTCPayServer.Views.Stores
|
||||
@using BTCPayServer.Client
|
||||
@inject BTCPayNetworkProvider _btcPayNetworkProvider
|
||||
@{
|
||||
var walletId = Context.GetRouteValue("walletId")?.ToString();
|
||||
var storeId = Context.GetRouteValue("storeId")?.ToString();
|
||||
var cryptoCode = Context.GetRouteValue("cryptoCode")?.ToString();
|
||||
var wallet = walletId != null ? WalletId.Parse(walletId) : new WalletId(storeId, cryptoCode);
|
||||
var network = _btcPayNetworkProvider.GetNetwork<BTCPayNetwork>(wallet.CryptoCode);
|
||||
}
|
||||
<nav id="SectionNav">
|
||||
<div class="nav">
|
||||
<a class="nav-link @ViewData.IsActivePage(WalletsNavPages.Transactions)" asp-controller="UIWallets" asp-action="WalletTransactions" asp-route-walletId="@wallet" id="SectionNav-Transactions" permission="@Policies.CanModifyStoreSettings">Transactions</a>
|
||||
@if (!network.ReadonlyWallet)
|
||||
{
|
||||
<a class="nav-link @ViewData.IsActivePage(WalletsNavPages.Send)" asp-controller="UIWallets" asp-action="WalletSend" asp-route-walletId="@wallet" id="SectionNav-Send" permission="@Policies.CanModifyStoreSettings">Send</a>
|
||||
}
|
||||
<a class="nav-link @ViewData.IsActivePage(WalletsNavPages.Receive)" asp-controller="UIWallets" asp-action="WalletReceive" asp-route-walletId="@wallet" id="SectionNav-Receive" permission="@Policies.CanModifyStoreSettings">Receive</a>
|
||||
<a class="nav-link @ViewData.IsActivePage(WalletsNavPages.Rescan)" asp-controller="UIWallets" asp-action="WalletRescan" asp-route-walletId="@wallet" id="SectionNav-Rescan" permission="@Policies.CanModifyServerSettings">Rescan</a>
|
||||
@if (!network.ReadonlyWallet)
|
||||
{
|
||||
<a class="nav-link @ViewData.IsActivePage(WalletsNavPages.PSBT)" asp-controller="UIWallets" asp-action="WalletPSBT" asp-route-walletId="@wallet" id="SectionNav-PSBT" permission="@Policies.CanModifyStoreSettings">PSBT</a>
|
||||
}
|
||||
<a class="nav-link @ViewData.IsActivePage(WalletsNavPages.Settings) @ViewData.IsActivePage(StoreNavPages.OnchainSettings)" asp-controller="UIStores" asp-action="WalletSettings" asp-route-cryptoCode="@wallet.CryptoCode" asp-route-storeId="@wallet.StoreId" id="SectionNav-Settings" permission="@Policies.CanModifyStoreSettings">Settings</a>
|
||||
<vc:ui-extension-point location="wallet-nav" model="@Model"/>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="sticky-header-setup"></div>
|
||||
<header class="sticky-header">
|
||||
<vc:wallet-nav wallet-id="wallet"/>
|
||||
</header>
|
||||
<script>
|
||||
const { offsetHeight } = document.querySelector('.sticky-header-setup + .sticky-header');
|
||||
document.documentElement.style.scrollPaddingTop = `calc(${offsetHeight}px + var(--btcpay-space-m))`;
|
||||
</script>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
<symbol id="onion" viewBox="0 0 61 91"><g fill="currentColor"><path d="m34.9 6.8-2.4 9.6C35.9 9.6 41.4 4.5 47.7 0c-4.6 5.3-8.8 10.6-11.3 16C40.7 9.9 46.5 6.6 53 4.3 44.3 12 37.4 20.4 32.2 28.7L28 26.9c.7-6.7 3.2-13.5 6.9-20.1z"/><path d="m31.7 28.3 2.9 1.5c-.3 1.9.1 6.1 2 7.1 8.4 5.2 16.2 10.8 19.3 16.5 11 19.9-7.7 38.4-24 36.6 8.8-6.5 11.4-19.9 8.1-34.6-1.3-5.7-3.4-10.9-7.1-16.8-1.6-2.7-1-6.3-1.2-10.3zM28.5 37.8c-.6 3.1-1.3 8.7-4 10.8-1.1.8-2.3 1.6-3.5 2.4-4.9 3.3-9.7 6.4-11.9 14.3-.5 1.7-.1 3.5.3 5.2 1.2 4.9 4.6 10.1 7.3 13.2 0 .1.5.5.5.6 2.2 2.6 2.9 3.4 11.3 5.3l-.2.9c-5.1-1.3-9.2-2.6-11.9-5.6 0-.1-.5-.5-.5-.5-2.8-3.2-6.3-8.6-7.5-13.7-.5-2-.9-3.6-.3-5.7 2.3-8.2 7.3-11.5 12.3-14.9 1.1-.7 2.5-1.4 3.6-2.3 2.3-1.5 3.4-6.2 4.5-10z"/><path d="M30.7 50.8c.1 3.5-.3 5.3.6 7.8.5 1.5 2.4 3.5 2.9 5.5.7 2.6 1.5 5.5 1.5 7.3 0 2-.1 5.8-1 9.8-.7 3.3-2.2 6.2-4.8 7.8-2.7-.5-5.8-1.5-7.6-3.1-3.6-3.1-6.7-8.3-7.1-12.8-.3-3.7 3.1-9.2 7.9-11.9 4-2.4 5-5 5.9-9.4-1.2 3.8-2.4 6.9-6.3 9-5.7 3-8.6 7.9-8.3 12.7.4 6.1 2.8 10.2 7.6 13.5 2 1.4 5.8 2.9 8.2 3.3V90c1.8-.3 4.1-3.3 5.3-7.2 1-3.6 1.4-8.1 1.3-11-.1-1.7-.8-5.3-2.2-8.6-.7-1.8-1.9-3.6-2.6-4.9-.9-1.5-.9-4.3-1.3-7.5z"/><path d="M30.1 64.5c.1 2.4 1 5.4 1.4 8.5.3 2.3.2 4.6.1 6.6-.1 2.3-.8 6.5-1.9 8.6-1-.5-1.4-1-2.1-1.8-.8-1.1-1.4-2.3-1.9-3.6-.4-1-.9-2.2-1.1-3.5-.3-2-.2-5.2 2.1-8.4 1.8-2.6 2.2-2.8 2.8-5.7-.8 2.6-1.4 2.9-3.3 5.1-2.1 2.4-2.4 6-2.4 8.9 0 1.2.5 2.6 1 3.8.5 1.3 1 2.7 1.7 3.7 1.1 1.6 2.5 2.6 3.2 2.7v-.1c1.3-1.5 2.1-2.9 2.4-4.4.3-1.8.4-3.5.6-5.6.2-1.8.1-4.1-.4-6.5-.6-3-1.7-6.1-2.2-8.3z"/><path d="M30.5 35c.1 3.5.3 10 1.3 12.6.3.9 2.8 4.7 4.5 9.4 1.2 3.2 1.5 6.2 1.7 7.1.8 3.8-.2 10.3-1.5 16.4-.7 3.3-3 7.4-5.6 9l-.5.9c1.5-.1 5.1-3.6 6.4-8.1 2.2-7.5 3-11 2-19.4-.1-.8-.5-3.6-1.8-6.5-1.9-4.5-4.6-8.8-4.9-9.7-.7-1.4-1.5-7.6-1.6-11.7z"/><path d="M31.7 28.6c-.2 3.6-.2 6.4.4 9.1.7 2.9 4.5 7.1 6.1 11.9 3 9.2 2.2 21.2.1 30.5-.8 3.3-4.6 8.1-8.5 9.6l2.8.7c1.5-.1 5.5-3.8 7.1-8 2.5-6.7 3-14.6 2-23-.1-.8-1.4-8-2.7-11-1.8-4.5-4.7-7.7-5.7-10.5-.8-2.1-1.1-7.7-.6-8.8l-1-.5z"/><path d="M51.7 46.3c-2.9-2.6-6.5-4.8-10.3-6.9-1.7-.9-6.9-5-5.1-10.8l-13.1-5.4-.9.7c4.4 7.9 2.1 12.1-.1 13.5-4.4 3-10.8 6.8-13.9 10.1C2.2 53.8.4 59.8 1 67.6c.6 10.1 7.9 18.5 17.8 21.8 4.3 1.4 8.3 1.6 12.7 1.6 7.1 0 14.5-1.9 19.8-6.3 5.7-4.7 9-11.8 9-19.1 0-7.3-3.1-14.3-8.6-19.3zm-1.9 36.9c-4.9 4-13.7 6.8-18.4 6.6-5.2-.3-10.3-1.1-14.8-3.3C8.7 82.7 3.5 74.4 3.1 67.7 2.4 54 9 50.1 15.1 45.1c3.4-2.8 8.2-4.2 10.9-9.2.5-1.1.8-3.5.2-6-.3-.9-1.5-3.9-2-4.6l9.8 4.3c-1.2 4.5 2.5 9.2 5.5 10.9 3 1.7 7.7 4.9 10.6 7.5 5.1 4.5 7.7 10.9 7.7 17.6 0 6.7-2.8 13.3-8 17.6z"/></g></symbol>
|
||||
<symbol id="back" viewBox="0 0 21 18"><path d="M7.63754 1.10861L0.578503 8.16764C0.119666 8.62648 0.119666 9.37121 0.578503 9.83122L7.63754 16.8902C8.09637 17.3491 8.8411 17.3491 9.30111 16.8902C9.53053 16.6608 9.64583 16.3608 9.64583 16.0585C9.64583 15.7561 9.53053 15.4561 9.30111 15.2267L4.25038 10.1759H19.0579C19.7085 10.1759 20.2344 9.65004 20.2344 8.99943C20.2344 8.34882 19.7085 7.82293 19.0579 7.82293L4.25038 7.82293L9.30111 2.77219C9.53053 2.54277 9.64583 2.24276 9.64583 1.9404C9.64583 1.63804 9.53053 1.33803 9.30111 1.10861C8.84228 0.649771 8.09755 0.649771 7.63754 1.10861Z" fill="currentColor" /></symbol>
|
||||
<symbol id="close" viewBox="0 0 16 16"><path d="M9.38526 8.08753L15.5498 1.85558C15.9653 1.43545 15.9653 0.805252 15.5498 0.385121C15.1342 -0.0350102 14.5108 -0.0350102 14.0952 0.385121L7.93072 6.61707L1.76623 0.315098C1.35065 -0.105033 0.727273 -0.105033 0.311688 0.315098C-0.103896 0.73523 -0.103896 1.36543 0.311688 1.78556L6.47618 8.0175L0.311688 14.2495C-0.103896 14.6696 -0.103896 15.2998 0.311688 15.7199C0.519481 15.93 0.796499 16 1.07355 16C1.35061 16 1.62769 15.93 1.83548 15.7199L7.99997 9.48797L14.1645 15.7199C14.3722 15.93 14.6493 16 14.9264 16C15.2034 16 15.4805 15.93 15.6883 15.7199C16.1039 15.2998 16.1039 14.6696 15.6883 14.2495L9.38526 8.08753Z" fill="currentColor"/></symbol>
|
||||
<symbol id="copy" viewBox="0 0 24 24" fill="none"><path d="M20 6H8a2 2 0 0 0-2 2v12c0 1.1.9 2 2 2h12a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2Zm0 13a1 1 0 0 1-1 1H9a1 1 0 0 1-1-1V9a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v10Z" fill="currentColor"/><path d="M4 5a1 1 0 0 1 1-1h12a1 1 0 1 0 0-2H4a2 2 0 0 0-2 2v13a1 1 0 1 0 2 0V5Z" fill="currentColor"/></symbol>
|
||||
<symbol id="caret-right" viewBox="0 0 24 24"><path d="M9.5 17L14.5 12L9.5 7" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/></symbol>
|
||||
<symbol id="caret-down" viewBox="0 0 24 24"><path d="M7 9.5L12 14.5L17 9.5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/></symbol>
|
||||
<symbol id="new-store" viewBox="0 0 32 32"><path d="M16 10V22" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M22 16H10" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><circle fill="none" cx="16" cy="16" r="15" stroke="currentColor" stroke-width="2"/></symbol>
|
||||
|
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
@ -1,7 +1,7 @@
|
|||
const confirmCopy = (el, message) => {
|
||||
el.innerText = message;
|
||||
setTimeout(function () {
|
||||
el.innerText = el.dataset.clipboardInitialText;
|
||||
el.innerHTML = el.dataset.clipboardInitial;
|
||||
}, 2500);
|
||||
}
|
||||
|
||||
|
@ -10,8 +10,8 @@ window.copyToClipboard = function (e, data) {
|
|||
const item = e.target.closest('[data-clipboard]');
|
||||
const confirm = item.querySelector('[data-clipboard-confirm]') || item;
|
||||
const message = confirm.getAttribute('data-clipboard-confirm') || 'Copied ✔';
|
||||
if (!confirm.dataset.clipboardInitialText) {
|
||||
confirm.dataset.clipboardInitialText = confirm.innerText;
|
||||
if (!confirm.dataset.clipboardInitial) {
|
||||
confirm.dataset.clipboardInitial = confirm.innerHTML;
|
||||
confirm.style.minWidth = confirm.getBoundingClientRect().width + 'px';
|
||||
}
|
||||
if (navigator.clipboard) {
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
--icon-size: 1.5rem;
|
||||
|
||||
height: var(--header-height);
|
||||
z-index: 9999999;
|
||||
z-index: 1031; /* needs a value between fixed and the offcanvas backdrop, see https://getbootstrap.com/docs/5.1/layout/z-index/ */
|
||||
}
|
||||
|
||||
#mainMenuHead {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
.qr-container {
|
||||
position: relative;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.qr-container svg {
|
||||
|
|
|
@ -65,6 +65,11 @@ hr.primary {
|
|||
}
|
||||
}
|
||||
|
||||
a.unobtrusive-link {
|
||||
color: inherit;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
|
||||
/* Info icons in main headline */
|
||||
h2 small .fa-question-circle-o {
|
||||
position: relative;
|
||||
|
|
Loading…
Add table
Reference in a new issue